import { operation, tags, requestBodySchema, response200, response500, security, speciesSchema, statusSchema, } from '../chunks.ts'; // The medals block shared by the view_profile and edit_profile responses. Distinct from the one in // view_public_profile, which omits `public` since every medal shown there is public by definition. const profileMedalsSchema = { type: 'object', description: 'Keyed by medal id.', additionalProperties: { type: 'object', required: ['name', 'image', 'date', 'public', 'times_earned'], properties: { name: { type: 'string' }, image: { type: 'string' }, date: { type: 'string' }, public: { type: 'integer', enum: [1, 0] }, times_earned: { type: 'integer' }, }, }, }; const viewBoostsSchema = { type: 'object', properties: { spy_training: { type: 'string' }, ore: { type: 'string' }, water: { type: 'string' }, storage: { type: 'string' }, food: { type: 'string' }, happiness: { type: 'string' }, building: { type: 'string' }, energy: { type: 'string' }, }, required: ['spy_training', 'ore', 'water', 'storage', 'food', 'happiness', 'building', 'energy'], }; export const empire = { '/v2/empire/is_name_available': { post: { ...tags('empire'), ...operation( 'Check whether an empire name is available.', 'Returns 1 if the name is available, or throws an exception if it is not. Throws 1000.' ), responses: { ...response200( 'Returns a 1 if the name is available, or throws an exception if it is not. Throws 1000.', { type: 'integer', enum: [1, 0] } ), ...response500(), }, ...requestBodySchema({ type: 'object', required: ['name'], properties: { name: { type: 'string', description: 'The name of the empire to search for.' }, }, }), }, }, '/v2/empire/logout': { post: { ...tags('empire'), ...security(), ...operation('End the current session.', 'Ends a session. Returns 1. Throws 1006.'), responses: { ...response200('Ends a session. Returns 1. Throws 1006.', { type: 'integer', enum: [1] }), ...response500(), }, }, }, '/v2/empire/login': { post: { ...tags('empire'), ...operation( 'Log in to an empire and start a session.', 'Confirms the password matches the empire and returns a session id alongside the empire and server status. A session survives up to 2 hours of inactivity, so there is no need to log in again while an existing session is still valid. Throws 1004 and 1005.' ), responses: { ...response200( 'Confirms the password matches the empire and returns a session id alongside the empire and server status. A session survives up to 2 hours of inactivity, so there is no need to log in again while an existing session is still valid. Throws 1004 and 1005.', { type: 'object', properties: { session_id: { type: 'string' }, status: statusSchema() }, required: ['session_id', 'status'], } ), ...response500(), }, ...requestBodySchema({ type: 'object', required: ['empire_name', 'password', 'api_key'], properties: { empire_name: { type: 'string', description: 'The name of the empire.' }, password: { type: 'string', format: 'password', description: 'The password to authenticate to the empire.', }, api_key: { type: 'string', description: "Your client's unique API key, identifying it from all other clients. See ApiKeys for details.", }, }, }), }, }, '/v2/empire/fetch_captcha': { post: { ...tags('empire'), ...operation( 'Fetch a captcha for empire creation.', "Retrieves a captcha that is required in order to call the create method. Display the resulting captcha in your creation form and then call create with the user's response." ), responses: { ...response200( "Retrieves a captcha that is required in order to call the create method. Display the resulting captcha in your creation form and then call create with the user's response.", { type: 'object', required: ['guid', 'url'], properties: { guid: { type: 'string' }, url: { type: 'string' } }, } ), ...response500(), }, }, }, '/v2/empire/create': { post: { ...tags('empire'), ...operation( 'Create a new empire.', 'Creates a new empire and returns its empire_id. The empire is not playable yet — either call update_species and then found, or skip the species step and call found directly. Throws 1000, 1001, 1002, and 1014. On a 1014 the error data carries fresh captcha information that must be used for the next attempt, since a captcha cannot be used more than once.' ), responses: { ...response200( 'Creates a new empire and returns its empire_id. The empire is not playable yet — either call update_species and then found, or skip the species step and call found directly. Throws 1000, 1001, 1002, and 1014. On a 1014 the error data carries fresh captcha information that must be used for the next attempt, since a captcha cannot be used more than once.', { type: 'integer', description: 'The new empire id.' } ), ...response500(), }, ...requestBodySchema({ type: 'object', required: ['name', 'captcha_guid', 'captcha_solution'], properties: { name: { type: 'string', description: 'The name of the empire to create.' }, password: { type: 'string', description: 'The password to log in to the empire. Must be between 6 and 30 characters.', }, password1: { type: 'string', description: 'Retyping the password again. This must match password to succeed. Required whenever password is supplied.', }, captcha_guid: { type: 'string', description: 'Must match the guid field returned by the fetch_captcha method.', }, captcha_solution: { type: 'string', description: 'The text typed in by the user as the solution of the captcha.', }, email: { type: 'string', description: "The user's email address. Not required, but used for system vital functions like password recovery.", }, invite_code: { type: 'string', description: 'A 36 character code that was sent to the user by a friend. Usable only once, it ensures that their friend gets a home planet in relatively close proximity to their own.', }, }, }), }, }, '/v2/empire/found': { post: { ...tags('empire'), ...operation( 'Found an empire on its home world.', 'Sets up an empire on its new home world. Once this method is called, the species can no longer be modified. The returned welcome_message_id identifies an inbox message that starts the tutorial, so the user can be prompted to read it right away.' ), responses: { ...response200( 'Sets up an empire on its new home world. Once this method is called, the species can no longer be modified. The returned welcome_message_id identifies an inbox message that starts the tutorial, so the user can be prompted to read it right away.', { type: 'object', required: ['session_id', 'welcome_message_id', 'status'], properties: { session_id: { type: 'string' }, welcome_message_id: { type: 'integer' }, status: statusSchema(), }, } ), ...response500(), }, ...requestBodySchema({ type: 'object', required: ['empire_id', 'api_key'], properties: { empire_id: { type: 'integer', description: 'The empire to found.' }, api_key: { type: 'string', description: "Your client's unique API key, identifying it from all other clients. See ApiKeys for details.", }, invite_code: { type: 'string', description: 'Deprecated here. Pass invite_code to the create method instead.', }, }, }), }, }, '/v2/empire/get_invite_friend_url': { post: { ...tags('empire'), ...security(), ...operation( 'Get a referral URL for inviting friends.', 'Returns a URL that can be pasted into a blog, forum, or whatever to invite friends.' ), responses: { ...response200( 'Returns a URL that can be pasted into a blog, forum, or whatever to invite friends.', { type: 'object', required: ['referral_url', 'status'], properties: { referral_url: { type: 'string' }, status: statusSchema() }, } ), ...response500(), }, }, }, '/v2/empire/invite_friend': { post: { ...tags('empire'), ...security(), ...operation( 'Email a friend an invitation code.', 'Sends an invitation code to a friend so that they can start in the same zone as your empire.' ), responses: { ...response200( 'Sends an invitation code to a friend so that they can start in the same zone as your empire. Each not_sent entry pairs the address with the [code, message] reason it could not be invited.', { type: 'object', required: ['status'], properties: { sent: { type: 'array', items: { type: 'string' } }, not_sent: { type: 'array', items: { type: 'object', required: ['address', 'reason'], properties: { address: { type: 'string' }, reason: { type: 'array' } }, }, }, status: statusSchema(), }, } ), ...response500(), }, ...requestBodySchema({ type: 'object', required: ['email'], properties: { email: { type: 'string', description: 'The email address of your friend, or a comma separated string of email addresses.', }, custom_message: { type: 'string', description: 'An optional message the user can type to invite their friend. Defaults to "I\'m having a great time with this new game called Lacuna Expanse. Come play with me." The empire name, friend code, and server URI are appended to whatever is sent.', }, }, }), }, }, '/v2/empire/get_status': { post: { ...tags('empire'), ...security(), ...operation( 'Get the current state of the empire.', 'Returns information about the current state of the empire. You should probably never call this directly — it is a wasted call, since the same data comes back in the status block of every relevant request. Throws 1002.' ), responses: { ...response200( 'Returns information about the current state of the empire. You should probably never call this directly — it is a wasted call, since the same data comes back in the status block of every relevant request. Throws 1002.', { type: 'object', required: ['empire', 'server'], properties: { server: { $ref: '#/components/schemas/server_status' }, empire: { $ref: '#/components/schemas/empire_status' }, }, } ), ...response500(), }, }, }, '/v2/empire/view_profile': { post: { ...tags('empire'), ...security(), ...operation( 'View the editable empire profile.', "Provides a list of the editable properties of the current empire's profile. See also the edit_profile and view_public_profile methods." ), responses: { ...response200( "Provides a list of the editable properties of the current empire's profile. See also the edit_profile and view_public_profile methods.", { type: 'object', required: ['profile', 'status'], properties: { profile: { type: 'object', required: [ 'description', 'status_message', 'medals', 'city', 'country', 'notes', 'skype', 'player_name', 'skip_happiness_warnings', 'skip_resource_warnings', 'skip_pollution_warnings', 'skip_medal_messages', 'skip_found_nothing', 'skip_excavator_resources', 'skip_excavator_glyph', 'skip_excavator_plan', 'skip_spy_recovery', 'skip_probe_detected', 'skip_attack_messages', 'skip_incoming_ships', 'email', 'sitter_password', ], properties: { description: { type: 'string' }, status_message: { type: 'string' }, medals: profileMedalsSchema, city: { type: 'string' }, country: { type: 'string' }, notes: { type: 'string' }, skype: { type: 'string' }, player_name: { type: 'string' }, skip_happiness_warnings: { type: 'integer', enum: [1, 0] }, skip_resource_warnings: { type: 'integer', enum: [1, 0] }, skip_pollution_warnings: { type: 'integer', enum: [1, 0] }, skip_medal_messages: { type: 'integer', enum: [1, 0] }, skip_found_nothing: { type: 'integer', enum: [1, 0] }, skip_excavator_resources: { type: 'integer', enum: [1, 0] }, skip_excavator_glyph: { type: 'integer', enum: [1, 0] }, skip_excavator_plan: { type: 'integer', enum: [1, 0] }, skip_spy_recovery: { type: 'integer', enum: [1, 0] }, skip_probe_detected: { type: 'integer', enum: [1, 0] }, skip_attack_messages: { type: 'integer', enum: [1, 0] }, skip_incoming_ships: { type: 'integer', enum: [1, 0] }, email: { type: 'string' }, sitter_password: { type: 'string' }, }, }, status: statusSchema(), }, } ), ...response500(), }, }, }, '/v2/empire/edit_profile': { post: { ...tags('empire'), ...security(), ...operation( 'Edit the empire profile.', 'Edits properties of an empire. Returns the same payload as view_profile. Only the properties present in the request are updated. Throws 1005 and 1009.' ), responses: { ...response200( 'Edits properties of an empire. Returns the same payload as view_profile. Only the properties present in the request are updated. See also the view_profile and view_public_profile methods. Throws 1005 and 1009.', { type: 'object', required: ['profile', 'status'], properties: { profile: { type: 'object', required: [ 'description', 'status_message', 'medals', 'city', 'country', 'notes', 'skype', 'player_name', 'skip_happiness_warnings', 'skip_resource_warnings', 'skip_pollution_warnings', 'skip_medal_messages', 'skip_found_nothing', 'skip_excavator_resources', 'skip_excavator_glyph', 'skip_excavator_plan', 'skip_spy_recovery', 'skip_probe_detected', 'skip_attack_messages', 'skip_incoming_ships', 'email', 'sitter_password', ], properties: { description: { type: 'string' }, status_message: { type: 'string' }, medals: profileMedalsSchema, city: { type: 'string' }, country: { type: 'string' }, notes: { type: 'string' }, skype: { type: 'string' }, player_name: { type: 'string' }, skip_happiness_warnings: { type: 'integer', enum: [1, 0] }, skip_resource_warnings: { type: 'integer', enum: [1, 0] }, skip_pollution_warnings: { type: 'integer', enum: [1, 0] }, skip_medal_messages: { type: 'integer', enum: [1, 0] }, skip_found_nothing: { type: 'integer', enum: [1, 0] }, skip_excavator_resources: { type: 'integer', enum: [1, 0] }, skip_excavator_glyph: { type: 'integer', enum: [1, 0] }, skip_excavator_plan: { type: 'integer', enum: [1, 0] }, skip_spy_recovery: { type: 'integer', enum: [1, 0] }, skip_probe_detected: { type: 'integer', enum: [1, 0] }, skip_attack_messages: { type: 'integer', enum: [1, 0] }, skip_incoming_ships: { type: 'integer', enum: [1, 0] }, email: { type: 'string' }, sitter_password: { type: 'string' }, }, }, status: statusSchema(), }, } ), ...response500(), }, ...requestBodySchema({ type: 'object', required: ['profile'], properties: { profile: { type: 'object', description: 'The properties to be edited. Set one or all of them — only those set will be updated.', properties: { description: { type: 'string', description: 'A description of the empire. Limited to 1024 characters and cannot contain < or >.', }, status_message: { type: 'string', description: "A message to indicate what you're doing, how you're feeling, or other status indicator. Limited to 100 characters, cannot be blank, and cannot contain @, &, <, >, or ;.", }, public_medals: { type: 'array', items: { type: 'number' }, description: 'The ids of the medals the user wishes to display in the public profile.', }, city: { type: 'string', description: 'The city in which the player resides. Limited to 100 characters and cannot contain @, &, <, >, or ;.', }, country: { type: 'string', description: 'The country in which the player resides. Limited to 100 characters and cannot contain @, &, <, >, or ;.', }, notes: { type: 'string', description: 'A text blob where the user can write down whatever they want to store in their account. Limited to 1024 characters and cannot contain @, &, <, >, or ;.', }, skype: { type: 'string', description: 'The username this player uses on Skype. Limited to 100 characters and cannot contain @, &, <, >, or ;.', }, player_name: { type: 'string', description: 'The real name or online identity of this player. Limited to 100 characters and cannot contain @, &, <, >, or ;.', }, skip_happiness_warnings: { type: 'integer', enum: [1, 0], description: 'Defaults to 0. Set to 1 to stop receiving messages about unhappy citizens. WARNING: these messages are there for your own protection — turn them off at your own risk.', }, skip_resource_warnings: { type: 'integer', enum: [1, 0], description: 'Defaults to 0. Set to 1 to stop receiving messages about a lack of resources to keep buildings running. WARNING: these messages are there for your own protection — turn them off at your own risk.', }, skip_pollution_warnings: { type: 'integer', enum: [1, 0], description: 'Defaults to 0. Set to 1 to stop receiving messages about excess waste causing pollution. WARNING: these messages are there for your own protection — turn them off at your own risk.', }, skip_medal_messages: { type: 'integer', enum: [1, 0], description: "Defaults to 0. Set to 1 to stop receiving messages about the medals they've earned.", }, skip_found_nothing: { type: 'integer', enum: [1, 0], description: 'Defaults to 0. Set to 1 to stop receiving messages when excavators find nothing.', }, skip_excavator_resources: { type: 'integer', enum: [1, 0], description: 'Defaults to 0. Set to 1 to stop receiving messages when excavators find resources.', }, skip_excavator_glyph: { type: 'integer', enum: [1, 0], description: 'Defaults to 0. Set to 1 to stop receiving messages when excavators find glyphs.', }, skip_excavator_plan: { type: 'integer', enum: [1, 0], description: 'Defaults to 0. Set to 1 to stop receiving messages when excavators find plans.', }, skip_spy_recovery: { type: 'integer', enum: [1, 0], description: 'Defaults to 0. Set to 1 to stop receiving spy recovery messages ("I\'m ready to work. What do you need from me?").', }, skip_probe_detected: { type: 'integer', enum: [1, 0], description: 'Defaults to 0. Set to 1 to stop receiving messages when a probe is detected.', }, skip_attack_messages: { type: 'integer', enum: [1, 0], description: 'Defaults to 0. Set to 1 to stop receiving messages about attacks.', }, skip_incoming_ships: { type: 'integer', enum: [1, 0], description: 'Controls the display of incoming ships (own, allied, foreign) on the map display. Defaults to 0, which shows them. Set to 1 to hide them, which can improve browser responsiveness.', }, email: { type: 'string', description: 'An email address that can be used for system functions like password recovery. Must either resemble an email address or be empty.', }, sitter_password: { type: 'string', description: 'A password that can be safely given to account sitters and alliance members. Must be between 6 and 30 characters.', }, }, }, }, }), }, }, '/v2/empire/view_public_profile': { post: { ...tags('empire'), ...security(), ...operation( "View another empire's public profile.", 'Provides a list of the data that is publicly known about an empire. Throws 1002.' ), responses: { ...response200( "Provides a list of the data that's publicly known about this empire. Throws 1002.", { type: 'object', properties: { profile: { type: 'object', properties: { city: { type: 'string' }, description: { type: 'string' }, medals: profileMedalsSchema, player_name: { type: 'string' }, id: { type: 'integer' }, skype: { type: 'string' }, name: { type: 'string' }, species: { type: 'string' }, country: { type: 'string' }, date_founded: { type: 'string' }, known_colonies: { type: 'array', items: { type: 'object', properties: { type: { type: 'string' }, id: { type: 'integer' }, star_name: { type: 'string' }, ore: { type: 'object', properties: { methane: { type: 'integer' }, fluorite: { type: 'integer' }, beryl: { type: 'integer' }, goethite: { type: 'integer' }, gold: { type: 'integer' }, chalcopyrite: { type: 'integer' }, anthracite: { type: 'integer' }, bauxite: { type: 'integer' }, galena: { type: 'integer' }, monazite: { type: 'integer' }, trona: { type: 'integer' }, halite: { type: 'integer' }, uraninite: { type: 'integer' }, zircon: { type: 'integer' }, chromite: { type: 'integer' }, kerogen: { type: 'integer' }, rutile: { type: 'integer' }, magnetite: { type: 'integer' }, sulfur: { type: 'integer' }, gypsum: { type: 'integer' }, }, required: [ 'methane', 'fluorite', 'beryl', 'goethite', 'gold', 'chalcopyrite', 'anthracite', 'bauxite', 'galena', 'monazite', 'trona', 'halite', 'uraninite', 'zircon', 'chromite', 'kerogen', 'rutile', 'magnetite', 'sulfur', 'gypsum', ], }, homeworld: { type: 'integer' }, x: { type: 'integer' }, size: { type: 'integer' }, star_id: { type: 'integer' }, name: { type: 'string' }, empire: { type: 'object', properties: { name: { type: 'string' }, is_isolationist: { type: 'integer' }, id: { type: 'integer' }, alignment: { type: 'string' }, }, required: ['name', 'is_isolationist', 'id', 'alignment'], }, orbit: { type: 'integer' }, zone: { type: 'string' }, y: { type: 'integer' }, image: { type: 'string' }, notes: { type: ['string', 'null'] }, water: { type: 'integer' }, }, required: [ 'type', 'id', 'star_name', 'x', 'size', 'star_id', 'name', 'orbit', 'zone', 'y', 'image', 'notes', 'water', ], }, }, status_message: { type: 'string' }, last_login: { type: 'string' }, colony_count: { type: 'integer' }, }, required: [ 'city', 'description', 'medals', 'player_name', 'id', 'skype', 'name', 'species', 'country', 'date_founded', 'known_colonies', 'status_message', 'last_login', 'colony_count', ], }, status: statusSchema(), }, required: ['profile', 'status'], } ), ...response500(), }, ...requestBodySchema({ type: 'object', required: ['empire_id'], properties: { empire_id: { type: 'integer', description: "The id of the empire for which you'd like to retrieve the public profile.", }, }, }), }, }, '/v2/empire/send_password_reset_message': { post: { ...tags('empire'), ...operation( 'Start a password recovery.', 'Starts a password recovery process by sending an email with a recovery key. Identify the empire by exactly one of empire_id, empire_name, or email.' ), responses: { ...response200( 'Starts a password recovery process by sending an email with a recovery key. Identify the empire by exactly one of empire_id, empire_name, or email.', { type: 'object', properties: { sent: { type: 'integer', enum: [1] } }, required: ['sent'], } ), ...response500(), }, ...requestBodySchema({ type: 'object', required: [], properties: { empire_id: { type: 'integer', description: 'The unique id of the empire to recover. Choose one of empire_id, empire_name, or email.', }, empire_name: { type: 'string', description: 'The full name of the empire. Choose one of empire_id, empire_name, or email.', }, email: { type: 'string', description: 'The email address associated with an empire. Choose one of empire_id, empire_name, or email.', }, }, }), }, }, '/v2/empire/reset_password': { post: { ...tags('empire'), ...operation( 'Reset a forgotten password.', 'Changes an empire password that has been forgotten, using the key emailed by send_password_reset_message. Returns the same response as login if successful.' ), responses: { ...response200( 'Change the empire password that has been forgotten. Returns the same response as `login` if successful.', { type: 'object', properties: { session_id: { type: 'string' }, status: statusSchema() }, required: ['session_id', 'status'], } ), ...response500(), }, ...requestBodySchema({ type: 'object', required: ['reset_key', 'password1', 'password2', 'api_key'], properties: { reset_key: { type: 'number', description: 'A key that was emailed to the user via the send_password_reset_message method.', }, password1: { type: 'string', description: 'The password to log in to the empire. Must be between 6 and 30 characters.', }, password2: { type: 'string', description: 'Retyping the password again. This must match password1 to succeed.', }, api_key: { type: 'string', description: "Your client's unique API key, identifying it from all other clients. See ApiKeys for details.", }, }, }), }, }, '/v2/empire/change_password': { post: { ...tags('empire'), ...security(), ...operation('Change the empire password.', 'Changes the empire password.'), responses: { ...response200('Change the empire password.', { type: 'object', properties: { status: statusSchema() }, required: ['status'], }), ...response500(), }, ...requestBodySchema({ type: 'object', required: ['password1', 'password2'], properties: { password1: { type: 'string', description: 'The password to log in to the empire. Must be between 6 and 30 characters.', }, password2: { type: 'string', description: 'Retyping the password again. This must match password1 to succeed.', }, }, }), }, }, '/v2/empire/find': { post: { ...tags('empire'), ...security(), ...operation( 'Find empires by name.', 'Finds empires by name. Returns a hash reference containing empire ids and empire names.' ), responses: { ...response200( 'Find an empire by name. Returns a hash reference containing empire ids and empire names.', { type: 'object', properties: { empires: { type: 'array', items: { type: 'object', properties: { id: { type: 'integer' }, name: { type: 'string' } }, required: ['id', 'name'], }, }, status: statusSchema(), }, required: ['empires', 'status'], } ), ...response500(), }, ...requestBodySchema({ type: 'object', required: ['name'], properties: { name: { type: 'string', description: "The name you're searching for. Case insensitive, and partial names work fine. Must be at least 3 characters.", }, }, }), }, }, '/v2/empire/set_status_message': { post: { ...tags('empire'), ...security(), ...operation( 'Set the empire status message.', 'Sets the empire status message, similar to what you might put on your social media updates, but about your empire.' ), responses: { ...response200( 'Sets the empire status message. Similar to what you might put on your social media updates, but about your empire.', { type: 'object', properties: { status: statusSchema() }, required: ['status'] } ), ...response500(), }, ...requestBodySchema({ type: 'object', required: ['message'], properties: { message: { type: 'string', description: "A message to indicate what you're doing, how you're feeling, or other status indicator. Limited to 100 characters, cannot be blank, and cannot contain @, &, <, >, or ;.", }, }, }), }, }, '/v2/empire/view_boosts': { post: { ...tags('empire'), ...security(), ...operation( 'View boost expiry dates.', 'Shows the dates at which boosts have expired or will expire. Boosts are subsidies applied to various resources using essentia.' ), responses: { ...response200( 'Shows the dates at which boosts have expired or will expire. Boosts are subsidies applied to various resources using essentia.', { type: 'object', properties: { boosts: viewBoostsSchema, status: statusSchema() }, required: ['boosts', 'status'], } ), ...response500(), }, }, }, '/v2/empire/boost_storage': { post: { ...tags('empire'), ...security(), ...operation( 'Boost storage on all planets for a week.', 'Spends 5 essentia and boosts storage (all 5 types) on all planets for 7 days. If a boost is already underway, calling again adds 7 more days. Throws 1011.' ), responses: { ...response200( 'Spends 5 essentia, and boosts storage (all 5 types) on all planets for 7 days. If a boost is already underway, calling again will add 7 more days. Throws 1011.', { type: 'object', properties: { boosts: viewBoostsSchema, status: statusSchema() }, required: ['boosts', 'status'], } ), ...response500(), }, ...requestBodySchema({ type: 'object', required: [], properties: { weeks: { type: 'integer', minimum: 1, description: 'Optional. The number of 7 day boost periods to buy at once, at 5 essentia each. Defaults to 1.', }, }, }), }, }, '/v2/empire/boost_food': { post: { ...tags('empire'), ...security(), ...operation( 'Boost food production on all planets for a week.', 'Spends 5 essentia and boosts food production on all planets for 7 days. If a boost is already underway, calling again adds 7 more days. Throws 1011.' ), responses: { ...response200( 'Spends 5 essentia, and boosts food production on all planets for 7 days. If a boost is already underway, calling again will add 7 more days. Throws 1011.', { type: 'object', properties: { boosts: viewBoostsSchema, status: statusSchema() }, required: ['boosts', 'status'], } ), ...response500(), }, ...requestBodySchema({ type: 'object', required: [], properties: { weeks: { type: 'integer', minimum: 1, description: 'Optional. The number of 7 day boost periods to buy at once, at 5 essentia each. Defaults to 1.', }, }, }), }, }, '/v2/empire/boost_water': { post: { ...tags('empire'), ...security(), ...operation( 'Boost water production on all planets for a week.', 'Spends 5 essentia and boosts water production on all planets for 7 days. If a boost is already underway, calling again adds 7 more days. Throws 1011.' ), responses: { ...response200( 'Spends 5 essentia, and boosts water production on all planets for 7 days. If a boost is already underway, calling again will add 7 more days. Throws 1011.', { type: 'object', properties: { boosts: viewBoostsSchema, status: statusSchema() }, required: ['boosts', 'status'], } ), ...response500(), }, ...requestBodySchema({ type: 'object', required: [], properties: { weeks: { type: 'integer', minimum: 1, description: 'Optional. The number of 7 day boost periods to buy at once, at 5 essentia each. Defaults to 1.', }, }, }), }, }, '/v2/empire/boost_energy': { post: { ...tags('empire'), ...security(), ...operation( 'Boost energy production on all planets for a week.', 'Spends 5 essentia and boosts energy production on all planets for 7 days. If a boost is already underway, calling again adds 7 more days. Throws 1011.' ), responses: { ...response200( 'Spends 5 essentia, and boosts energy production on all planets for 7 days. If a boost is already underway, calling again will add 7 more days. Throws 1011.', { type: 'object', properties: { boosts: viewBoostsSchema, status: statusSchema() }, required: ['boosts', 'status'], } ), ...response500(), }, ...requestBodySchema({ type: 'object', required: [], properties: { weeks: { type: 'integer', minimum: 1, description: 'Optional. The number of 7 day boost periods to buy at once, at 5 essentia each. Defaults to 1.', }, }, }), }, }, '/v2/empire/boost_ore': { post: { ...tags('empire'), ...security(), ...operation( 'Boost ore production on all planets for a week.', 'Spends 5 essentia and boosts ore production on all planets for 7 days. If a boost is already underway, calling again adds 7 more days. Throws 1011.' ), responses: { ...response200( 'Spends 5 essentia, and boosts ore production on all planets for 7 days. If a boost is already underway, calling again will add 7 more days. Throws 1011.', { type: 'object', properties: { boosts: viewBoostsSchema, status: statusSchema() }, required: ['boosts', 'status'], } ), ...response500(), }, ...requestBodySchema({ type: 'object', required: [], properties: { weeks: { type: 'integer', minimum: 1, description: 'Optional. The number of 7 day boost periods to buy at once, at 5 essentia each. Defaults to 1.', }, }, }), }, }, '/v2/empire/boost_happiness': { post: { ...tags('empire'), ...security(), ...operation( 'Boost happiness production on all planets for a week.', 'Spends 5 essentia and boosts happiness production on all planets for 7 days. If a boost is already underway, calling again adds 7 more days. Throws 1011.' ), responses: { ...response200( 'Spends 5 essentia, and boosts happiness production on all planets for 7 days. If a boost is already underway, calling again will add 7 more days. Throws 1011.', { type: 'object', properties: { boosts: viewBoostsSchema, status: statusSchema() }, required: ['boosts', 'status'], } ), ...response500(), }, ...requestBodySchema({ type: 'object', required: [], properties: { weeks: { type: 'integer', minimum: 1, description: 'Optional. The number of 7 day boost periods to buy at once, at 5 essentia each. Defaults to 1.', }, }, }), }, }, '/v2/empire/boost_building': { post: { ...tags('empire'), ...security(), ...operation( 'Boost build queues on all planets for a week.', 'Spends 5 essentia and boosts build queues on all planets for 7 days. If a boost is already underway, calling again adds 7 more days. It does not speed up builds already under way, only new builds added to a queue. Throws 1011.' ), responses: { ...response200( 'Spends 5 essentia, and boosts build queues on all planets for 7 days. If a boost is already underway, calling again will add 7 more days. It will not boost builds already under way, only new builds added to a build queue. Throws 1011.', { type: 'object', properties: { boosts: viewBoostsSchema, status: statusSchema() }, required: ['boosts', 'status'], } ), ...response500(), }, ...requestBodySchema({ type: 'object', required: [], properties: { weeks: { type: 'integer', minimum: 1, description: 'Optional. The number of 7 day boost periods to buy at once, at 5 essentia each. Defaults to 1.', }, }, }), }, }, '/v2/empire/boost_spy_training': { post: { ...tags('empire'), ...security(), ...operation( 'Boost spy training on all planets for a week.', 'Spends 5 essentia and boosts spy training speed on all planets by 50% for 7 days. If a boost is already underway, calling again adds 7 more days. Unlike the other boosts, this one also speeds up spies already in specialist training. Throws 1011.' ), responses: { ...response200( 'Spends 5 essentia, and boosts spy training speed on all planets by 50% for 7 days. If a boost is already underway, calling again will add 7 more days. Unlike the other boosts, this one also boosts spies already in specialist training. Throws 1011.', { type: 'object', properties: { boosts: viewBoostsSchema, status: statusSchema() }, required: ['boosts', 'status'], } ), ...response500(), }, ...requestBodySchema({ type: 'object', required: [], properties: { weeks: { type: 'integer', minimum: 1, description: 'Optional. The number of 7 day boost periods to buy at once, at 5 essentia each. Defaults to 1.', }, }, }), }, }, '/v2/empire/enable_self_destruct': { post: { ...tags('empire'), ...security(), ...operation( 'Start the self destruct countdown.', 'Enables a destruction countdown of 24 hours. Sometime after the timer runs out, the empire will vaporize.' ), responses: { ...response200( 'Enables a destruction countdown of 24 hours. Sometime after the timer runs out, the empire will vaporize.', { type: 'object', properties: { status: statusSchema() }, required: ['status'] } ), ...response500(), }, }, }, '/v2/empire/disable_self_destruct': { post: { ...tags('empire'), ...security(), ...operation( 'Cancel the self destruct countdown.', 'Disables the self destruction countdown.' ), responses: { ...response200('Disables the self destruction countdown.', { type: 'object', properties: { status: statusSchema() }, required: ['status'], }), ...response500(), }, }, }, '/v2/empire/redeem_essentia_code': { post: { ...tags('empire'), ...security(), ...operation( 'Redeem an essentia code.', "Redeems an essentia code and applies the essentia to the empire's balance." ), responses: { ...response200( "Redeems an essentia code and applies the essentia to the empire's balance.", { type: 'object', properties: { amount: { type: 'number' }, status: statusSchema() }, required: ['amount', 'status'], } ), ...response500(), }, ...requestBodySchema({ type: 'object', required: ['code'], properties: { code: { type: 'string', description: 'A 36 character string that was sent to the user via email.', }, }, }), }, }, '/v2/empire/update_species': { post: { ...tags('empire'), ...security(), ...operation( 'Update the species before founding.', "Updates the empire's species and returns 1. Can only be called after create and before found; calling it outside that window throws an exception. Use redefine_species once the empire is founded. Throws 1000, 1002, 1005, 1007, 1008, 1009, and 1010; the error data carries the offending field name when the problem can be attributed to a single field." ), responses: { ...response200( "Updates the empire's species and returns 1. Can only be called after create and before found; calling it outside that window throws an exception. Use redefine_species for an empire that has already been founded, and see get_species_templates for ready-made starting points. Throws 1000, 1002, 1005, 1007, 1008, 1009, and 1010 — the error data names the field that needs adjusting whenever the problem can be attributed to a single field.", { type: 'integer', enum: [1] } ), ...response500(), }, ...requestBodySchema({ type: 'object', required: ['empire_id', 'params'], properties: { empire_id: { type: 'integer', description: 'The id of the empire you wish to update a species for.', }, params: { ...speciesSchema(), description: 'The species definition. Every field except name and description is an integer, and those integers must add up to exactly 45.', }, }, }), }, }, '/v2/empire/redefine_species_limits': { post: { ...tags('empire'), ...operation( 'View the limits on redefining a species.', 'Returns the extra limits placed on an empire that wants to redefine its species, including the essentia cost, the settable orbit range, the minimum growth affinity, and whether a redefinition is currently allowed.' ), responses: { ...response200( 'Returns the extra limits placed upon an empire that wants to redefine its species, including the essentia cost, the settable orbit range, the minimum growth affinity, and whether a redefinition is currently allowed at all.', { type: 'object', required: ['essentia_cost', 'max_orbit', 'min_orbit', 'min_growth', 'can', 'status'], properties: { essentia_cost: { type: 'integer' }, max_orbit: { type: 'integer' }, min_orbit: { type: 'integer' }, min_growth: { type: 'integer' }, can: { type: 'integer', enum: [1, 0] }, reason: { type: 'string' }, status: statusSchema(), }, } ), ...response500(), }, }, }, '/v2/empire/redefine_species': { post: { ...tags('empire'), ...security(), ...operation( 'Redefine the species after founding.', "Spends essentia to redefine the empire's species affinities, name, and description. Only usable after the empire is founded; use update_species during creation. Once done it cannot be redone for one month, so prompt the user before submitting." ), responses: { ...response200( "Spends essentia to redefine the empire's species affinities, name, and description. Only usable after the empire has been founded — use update_species during empire creation instead. See also redefine_species_limits. WARNING: once this is done it cannot be redone for 1 month, so make sure the user is aware and prompt them appropriately before submitting.", { type: 'object', required: ['status'], properties: { status: statusSchema() } } ), ...response500(), }, ...requestBodySchema({ type: 'object', required: ['params'], properties: { params: { ...speciesSchema(), description: 'The species definition, same as the params of update_species. Every field except name and description is an integer, and those integers must add up to exactly 45.', }, }, }), }, }, '/v2/empire/view_species_stats': { post: { ...tags('empire'), ...security(), ...operation( 'View your species stats.', "Returns the stats associated with the empire's species as it was originally created. An empire can only view its own species stats through this method." ), responses: { ...response200( "Returns the stats associated with the empire's species as it was originally created. An empire can only view its own species stats through this method.", { type: 'object', required: ['species', 'status'], properties: { species: speciesSchema(), status: statusSchema() }, } ), ...response500(), }, }, }, '/v2/empire/get_species_templates': { post: { ...tags('empire'), ...operation( 'List species templates.', 'Returns the list of species templates that can be used to help the user populate the form for update_species.' ), responses: { ...response200( 'Returns the list of species templates that can be used to help the user populate the form for update_species.', { type: 'array', items: speciesSchema() } ), ...response500(), }, }, }, '/v2/empire/view_authorized_sitters': { post: { ...tags('empire'), ...security(), ...operation( 'List authorized sitters.', 'Returns the empires currently authorized to sit for this account.' ), responses: { ...response200('Lists the empires currently authorized to sit for this empire.', { type: 'object', required: ['sitters', 'status'], properties: { sitters: { type: 'array', items: { type: 'object', required: ['id', 'name', 'expiry'], properties: { id: { type: 'integer' }, name: { type: 'string' }, expiry: { type: 'string' }, }, }, }, status: statusSchema(), }, }), ...response500(), }, }, }, '/v2/empire/authorize_sitters': { post: { ...tags('empire'), ...security(), ...operation( 'Authorize sitters for this account.', 'Authorizes other empires to babysit this account. Each authorization is created if needed and granted for the full server-defined period. Returns the authorized sitters plus any rejected ids.' ), responses: { ...response200( 'Authorizes other empires to babysit this account. Each authorization is created if needed and granted for the full server-defined period. Returns the same list as view_authorized_sitters, plus any ids that were rejected.', { type: 'object', required: ['auths', 'status'], properties: { auths: { type: 'array', items: { type: 'object', required: ['id', 'name'], properties: { id: { type: 'integer' }, name: { type: 'string' } }, }, }, rejected_ids: { type: 'array', items: { type: 'object', required: ['id', 'reason'], properties: { id: { type: 'integer' }, reason: { type: 'string' } }, }, }, status: statusSchema(), }, } ), ...response500(), }, ...requestBodySchema({ type: 'object', description: 'One or more of the following options.', properties: { allied: { type: 'integer', enum: [1, 0], description: 'If true, all allies are automatically selected.', }, alliance: { type: 'string', description: 'The name of another alliance, all of whom are automatically selected.', }, alliance_id: { type: 'integer', description: 'The id of another alliance, all of whom are automatically selected.', }, empires: { type: 'array', items: { type: 'string' }, description: 'The ids and/or names of specific empires being authorized.', }, revalidate_all: { type: 'integer', enum: [1, 0], description: 'A quick way of selecting all currently-authorized empires in order to extend their authorization period.', }, }, }), }, }, '/v2/empire/deauthorize_sitters': { post: { ...tags('empire'), ...security(), ...operation( 'Remove authorized sitters.', 'Removes sitters from being permitted to sit this account.' ), responses: { ...response200( 'Removes sitters from being permitted to sit this account. Returns the same list as view_authorized_sitters.', { type: 'object', required: ['sitters', 'status'], properties: { sitters: { type: 'array', items: { type: 'object', required: ['id', 'name', 'expiry'], properties: { id: { type: 'integer' }, name: { type: 'string' }, expiry: { type: 'string' }, }, }, }, status: statusSchema(), }, } ), ...response500(), }, ...requestBodySchema({ type: 'object', description: 'Either `empires` or `deauthorize_all` must be provided.', properties: { empires: { type: 'array', items: { type: 'string' }, description: 'The ids (not names) of specific empires being removed. Takes precedence over deauthorize_all.', }, deauthorize_all: { type: 'integer', enum: [1], description: 'Removes every authorized sitter. Ignored if empires is given. Any value (even 0) is treated as true, so omit it rather than sending 0.', }, }, }), }, }, };