def publish_on_forum(context): if conf.settings.FORUM_CATEGORY_UID is None: raise dext_views.exceptions.ViewError( code='forum_category_not_specified', message= 'try to publish news on forum when FORUM_CATEGORY_ID has not specified' ) if forum_prototypes.SubCategoryPrototype.get_by_uid( conf.settings.FORUM_CATEGORY_UID) is None: raise dext_views.exceptions.ViewError( code='forum_category_not_exists', message= 'try to publish news on forum when FORUM_CATEGORY_ID has not exists' ) if context.news.forum_thread_id is not None: raise dext_views.exceptions.ViewError( code='forum_thread_already_exists', message= 'try to publish news on forum when FORUM_CATEGORY_ID has not specified' ) thread = forum_prototypes.ThreadPrototype.create( forum_prototypes.SubCategoryPrototype.get_by_uid( conf.settings.FORUM_CATEGORY_UID), caption=context.news.caption, author=accounts_logic.get_system_user(), text=context.news.content, markup_method=forum_relations.MARKUP_METHOD.MARKDOWN) context.news.forum_thread_id = thread.id logic.save_news(context.news) return dext_views.AjaxOk( content={'next_url': url('forum:threads:show', thread.id)})
def delete_conversation(context): tt_api.hide_conversation(account_id=context.account.id, partner_id=context.contact.id) return dext_views.AjaxOk()
def delete_all(context): tt_api.hide_all_messages(account_id=context.account.id) return dext_views.AjaxOk()
def enable(context): logic.enable_companion_record(context.companion) return dext_views.AjaxOk()
def create(context): news = logic.create_news(caption=context.form.c.caption, description=context.form.c.description, content=context.form.c.content) return dext_views.AjaxOk(content={'next_url': url('news:show', news.id)})
def api_show(context): return dext_views.AjaxOk(content=info.place_info( context.place, full_building_info=context.api_version != '2.0'))
def api_info(context): ''' Информация о текущем ходе и герое - **адрес:** /game/api/info - **http-метод:** GET - **версии:** 1.5 - **параметры:** * GET: account — идентификатор аккаунта * GET: client_turns — номера ходов, по отношению к которым можно вернуть сокращённую информацию о герое (только изменённые с этого времени поля). - **возможные ошибки**: нет Если параметр account не будет указан, то вернётся информация об игре текущего пользователя, а на запрос от неавторизованного пользователя — общая информация об игре (без информации об аккаунте и герое). Часть информации в ответе является личной и доступна только залогиненному игроку, для остальных на её месте будет валидная с точки зрения формата заглушка. Такая информация обозначена следующим образом: **[личная информация]**. Полный ответ имеет большой размер, поэтому реализован следующий механизм его сжатия: - в параметре client_turns можно передать список номеров ходов (через запятую), для которых на клиенте есть полная информация; - если сервер сможет, в ответе он вернёт только изменившуюся информацию о герое; - сокращению подвергается только информация в <hero_info>; - сокращение происходит удалением неизменившихся полей <hero_info> (только на верхнем уровне, без рекурсии); - чтобы получить полную информацию, скопируйте недостаующие поля из закэшированной на стороне клиента информации для хода, указанного в .account.hero.patch_turn; - сервер не гарантирует, что вернёт сокращённую информацию; - сервер может вернуть патч для любого из переданных в client_turns ходов; - имеет смысл в параметре client_turns передавать последние 2-3 хода; - обратите внимание, сжатие ответа применяется и к информации о противнике в PvP! Поэтому первый запрос при PvP всегда должен требовать полную информацию. Формат данных в ответе: { "mode": "pve"|"pvp", // режим героя "turn": { // информация о номере хода "number": <целое число>, // номер хода "verbose_date": "строка", // дата для игроков (в мире Сказки) "verbose_time": "строка" // время для игроков (в мире Сказки) }, "game_state": <целое число>, // состояние игры (остановлена/запущена, см. в описании API) "map_version": "строка", // версия актуальной карты игры "account": <account_info>|null, // информация о запрашиваемом аккаунте и герое "enemy": <account_info>|null // информация о противнике, если идёт pvp сражение } <account_info> = { "new_messages": <целое число>, // количество личных сообщений "id": <целое число>, // идентификатор аккаунта "last_visit": <timestamp>, // примерное время последнего посещения игры "is_own": true|false, // информация о собственном герое или о чужом "is_old": true|false, // информация устаревшая или нет "hero": <hero_info>, // информация о герое "in_pvp_queue": true|false // находится ли герой в очереди на арену } <hero_info> = { "patch_turn": null|<целое число>, // номер хода, для которого возвращается патч или null, если информация полная "energy":{ // энергия игрока [личная информация] "bonus": <целое число>, // дополнительная энергия "max": <целое число>, // максимальное количество "value": <целое число>, // текущее количество "discount": <целое число> // скидка энергии при её трате (например, от использования артефактов) }, "equipment":{ // экипировка героя, словарь <идентификатор типа экипировки, информация об артефакте> "<целое число>": <artifact_info> // идентификатор типа экипировки: информация об артефакте }, "cards":{ // карты судьбы [личная информация] "cards": [ // список карт <card_info> // информация о карте ], "help_count": <целое число>, // сколько помощи накоплено для получения новой карты "help_barrier": <целое число> // сколько всего помощи надо накопить для новой карты }, "companion": <companion_info>|null,// информация о спутнике "bag":{ // содержимое рюкзака, словарь <внутренний идентификатор предмета, описание> () "<целое число>": <artifact_info> // идентификатор слота: информация об артефакте }, "base":{ // базовые параметры героя "experience": <целое число>, // текущий опыт "race": <целое число>, // раса "health": <целое число>, // здоровье "name": "строка", // имя героя "level": <целое число>, // уровень героя "gender": <целое число>, // пол "experience_to_level": <целое число>, // абсолютное количество опыта до следующего уровня "max_health": <целое число>, // максимальное количество здоровья "destiny_points": <целое число> // сколько способностей сейчас может выбрать "money": <целое число>, // количество денег у героя "alive": true|false, // жив герой или мёртв }, "secondary":{ // второстепенные параметры "max_bag_size": <целое число>, // максимальный размер рюкзака "power": [<целое число>, <целое число>], // физическая сила, магическая сила "move_speed": <дробное число>, // скорость движения "loot_items_count": <целое число>, // количество лута в рюкзаке "initiative": <дробное число> // инициатива героя }, "diary": "строка", // версия дневника героя, если она изменилась, необходимо перезапросить дневни "messages":[ // сообщения из журнала [ // запись в задании <timestamp>, // timestamp создания сообщения "строка", // текстовое описание времени в игре "строка", // текст <целое число>|null, // идентификатор типа фразы, найти идентификатор типа фразы можно в адресе страницы лингвистики с фразами этого типа {"строка": "строка"} // словарь соотношения переменных и их значений (ВНИМАНИЕ! перечень переменных может изменяться без изменения версии этого метода) ] ], "habits": { // черты "строка": { // идентификатор черты "verbose": "строка", // текущее текстовое значение черты для игрока (название характера) "raw": <дробное число> // текущее числовое значение черты } }, "quests": { // информация о заданиях "quests": [ // список глобальных заданий { "line": [ // список «базовых» заданий (цепочка последовательных заданий) { "type": "строка", // тип задания "uid": "строка", // уникальный идентификатор задания "name": "строка", // название задания "action": "строка", // описание текущего действия героя в задании "choice": "строка"|null, // текущий выбор героя в задании "choice_alternatives": [ // альтернативные выборы [ "строка", // уникальный идентификатор выбора "строка" // текстовое описание выбора ] ], "experience": <целое число>, // количество опыта за задание "power": <целое число>, // количество влияния за задание "actors": [ // список «актёров», участвующих в задании [ "строка", // название актёра <целое число>", // тип актёра (список типов приведён в описании API) <quest_actor_info> // данные, специфичные для конкретного типа актёра ] ] } ] } ] }, "action":{ // текущее действие "percents": <дробное число>, // процент выполнения "description": "строка", // описание "info_link": "url"|null // ссылка на доп. информацию "type": <целое число> // идентификатор типа действия "data": null|<словарь> // дополнительная информация о действиии или null, если такой нет }, "position":{ // позиция героя на клеточной карте "x": <дробное число>, // координата x "y": <дробное число>, // координата y "dx": <дробное число>, // направление взгляда по x "dy": <дробное число>, // направленеи взгляда по y }, "permissions": { // права на выполнение различных операций "can_participate_in_pvp": true|false, // может ли участвовать в pvp "can_repair_building": true|false, // может ли чинить здания }, "might": { // могущество игрока "value": <дробное число>, // величина "crit_chance": <дробное число>, // вероятность критического срабатывания помощи "pvp_effectiveness_bonus": <дробное число>, // бонус к эффективности в pvp от могущества "politics_power": <дробное число> // бонус к политическому влиянию героя }, "id": <целое число>, // идентификатор "actual_on_turn": <целое число>, // данные на какой ход предоставлены "sprite": <целое число> // идентификатор спрайта, которым отображается герой } <quest_actor_info> = <quest_actor_place_info>|<quest_actor_person_info>|<quest_actor_spending_info> <quest_actor_place_info> = { // информация о городе "id": <целое числое>, // идентификатор "name": "строка" // название города } <quest_actor_person_info> = { // информация о жителе города "id": <целое числое> // идентификатор "name": "строка", // имя "race": <целое числое>, // раса "gender": <целое числое>, // пол "profession": <целое числое>, // профессия "mastery_verbose": "строка", // профессия "place": <целое числое> // идентификатор города } <quest_actor_spending_info> = { // информация о целях накопления "goal": "строка" // описание цели накопления } <artifact_info> = { // информация об артефакте "name": "строка", // название "power": [<целое число>, <целое число>], // сила [физическая, магическая] "type": <целое число>, // тип "integrity": [<целое число>, <целое число>], // целостность [текущая, максимальная] "rarity": <целое число>, // редкость "effect": <целое число>, // тип эффекта на артефакте "special_effect": <целое число>, // тип особого свойства артефакта (эффекта, который действует независимо от редкости) "preference_rating": <дробное число>, // «полезность» артефакта с точки зрения героя "equipped": true|false, // может ли быть экипирован "id": <целое число> // уникальный идентификатор рода артефакта } <card_info> = { // информация о карте в колоде игрока "name": "строка", // название "type": <целое число>, // тип "rarity": <целое число>, // редкость карты "uid": <целое число>, // уникальный идентификатор в колоде игрока "auction": true|false // может быть продана на рынке } <companion_info> = { // информация о спутнике героя "type": <целое число>, // тип спутника "name": "строка", // название/имя спутника "health": <целое число>, // текущее здоровье "max_health": <целое число>, // максимальное здоровье "experience": <целое число>, // текущий опыт слаженности "experience_to_level": <целое число>, // опыта до следующего уровня слаженности "coherence": <целое число>, // текущая слаженность "real_coherence": <целое число> // полная слаженность (без учёта ограничений на максимум слаженности) } примечания: - если информация о герое устаревшая (is_old == true), то следует повторить запрос через несколько секунд (но лучше не злоупотреблять) ''' account = context.requested_account if account is None and context.account.is_authenticated: account = context.account data = game_logic.form_game_info(account=account, is_own=False if account is None else (context.account.id == account.id), client_turns=context.client_turns) if context.api_version in ('1.5', '1.4', '1.3', '1.2', '1.1', '1.0'): data = game_logic.game_info_from_1_6_to_1_5(data) if context.api_version in ('1.4', '1.3', '1.2', '1.1', '1.0'): data = game_logic.game_info_from_1_5_to_1_4(data) if context.api_version in ('1.3', '1.2', '1.1', '1.0'): data = game_logic.game_info_from_1_4_to_1_3(data) if context.api_version in ('1.2', '1.1', '1.0'): data = game_logic.game_info_from_1_3_to_1_2(data) if context.api_version in ('1.1', '1.0'): data = game_logic.game_info_from_1_2_to_1_1(data) if context.api_version == '1.0': data = game_logic.game_info_from_1_1_to_1_0(data) return dext_views.AjaxOk(content=data)
def region(context): return dext_views.AjaxOk( content=models.MapRegion.objects.latest('created_at').data)
def delete_all(context): prototypes.MessagePrototype.hide_all(account_id=context.account.id) return dext_views.AjaxOk()
def api_show(context): return dext_views.AjaxOk(content=info.person_info(context.person))
def api_show(context): u''' Подробная информация о конкретном городе - **адрес:** /game/map/places/<place>/api/show - **http-метод:** GET - **версии:** 1.0 - **параметры:** * URL place — идентификатор города - **возможные ошибки**: нет **Это экспериментальный метод, при появлении новой версии не гарантируется работоспособность предыдущей!** При завершении операции возвращается следующая информация: { "id": <целое число>, // идентификатор города "name": "строка", // название города "frontier": true|false, // является ли город фронтиром "new_for": <timestamp>, // время, до которого город считается новым "updated_at": <timestamp>, // время последнего обновления информации "description": "строка", // описание города "position": {"x": <целое число>, "y": <целое число>}, // координаты города "power": { "positive_bonus": <дробное число>, // бонус к положительному влиянию "negative_bonus": <дробное число> }, // бонус к отрицательному влиянию "persons": <persons_info>, // советники "keepers": <keepers_info>, // игроки, связанные с городом "parameters": <parameters_info>, // параметры города "demographics": <demographics_info>, // расовый состав "bills": <bills_info>, // действующие законы "specializations": <specializations_info>, // специализации "habits": <habits_info>, // черты города "chronicle": <chronicle_info>, // последние записи в летописи "accounts": <accounts_info>, // краткая дополнительная информация об игроках, связанных с городом "clans": <clans_info> // краткая дополнительная информация о кланах, связанных с городом } <persons_info> = [ { "id": <целое число>, // идентификатор советника "name": "строка", // имя "gender": <целое число>, // пол "race": <целое число>, // раса "type": <целое число>, // профессия "unfreeze_in": <дробное число>, // количество секунда до момента, когда советник может сам покинуть город "building": <целое число>|null, // идентификатор здания советника, если оно есть "keepers": <keepers_info> // информация об игроках, связанных с советником "mastery": {"value": <дробное число>, // числовое значение мастерства советника "name": "строка"}, // название уровня мастерства советника "power": { "percents": <дробное число>, // доля влияния советника (от 0 до 1) "positive_bonus": <дробное число>, // бонус к положительному влиянию "negative_bonus": <дробное число> }, // бонус к отрицательному влиянию "connections": [(<целое число>, <целое число>),…], // список социальных связей советника в виде <тип связи, идентификатор второго советника> }, … ] <keepers_info> = { "friends": [<целое число>, …], // список идентификаторов игроков, чьи герои помогают советника / городу "enemies": [<целое число>, …] // список идентификаторов игроков, чьи герои вредят советника / городу } <parameters_info> = { // информация обо всех параметрах города, по следующим ключам: // size — размер // economic — уровень экономики // politic_radius — радиус владений // terrain_radius — радиус изменений // stability — стабильность // production — производство // goods — текущие товары // keepers_goods — дары Хранителей // safety — безопасность // transport — транспорт // freedom — свобода // tax — пошлина "строка": {"value": <целое число>|<дробное число>, // текущее значение параметра "modifiers": null|[("строка", <дробное число>), …] } // если есть, список всех модификаторов параметрв в виде <название модификатора, значение> } <demographics_info> = [ { "race": <целое число>, // раса "percents": <дробное число>, // текущая доля (от 0 до 1) "delta": <дробное число>, // изменение в день "persons": <дробное число>}, // влияние советников (от 0 до 1) … ] <bills_info> = [ { "id": <целое число>, // идентификатор закона "caption": "строка", // название закона "properties": ["строка", …] }, // перечень описаний эффектов закона на город … ] <specializations_info> = { "current": <целое число>|null, // идентификатор текущей специализации "all": [ {"value": <дробное число>, // идентификатор специализации "power": <дробное число>, // текущее значение (развитие) "modifiers": [("строка", <дробное число>), …] } // список всех модификаторов специализации в виде <название модификатора, значение> "size_modifier": <дробное число>} // модификатор от размера города ] } <habits_info> = { // информация о каждой черте города в формате "идентификатор черты": {информация о черте} "<целое число>": {'interval': <целое число>, // идентификатор текущего «уровня» черты 'value': <дробное число>, // текущее абсолютное значенеи черты 'delta': <дробное число>, // величина изменения черты за один час 'positive_points': <дробное число>, // суммарное позитивное влияние героев на черту города 'negative_points': <дробное число> }, // суммарное негативное влияние героев на черту города … } <chronicle_info> = [("строка", "строка", "строка"), …] // последние записи из летописи о городе в формате ("короткая дата", "длинная дата", "текст") <accounts_info> = { "<целое число>": { // идентификатор игрока 'id': <целое число>, // идентификатор игрока 'name': "строка", // ник 'hero': { // краткая информация о герое 'id': <целое число>, // идентификатор 'name': "строка", // имя 'race': <целое число>, // раса 'gender': <целое число>, // пол 'level': <целое число> }, // уровень 'clan': <целое число>|null // идентификатор клана }, … } <clans_info> = { "<целое число>": { // идентификатор клана 'id': <целое число>, // идентификатор клана 'abbr': "строка", // аббревиатура 'name': "строка"}, // полное название … } ''' return dext_views.AjaxOk(content=logic.place_info(context.place))
def item_type_prices(context): prices, owner_prices = tt_api.item_type_prices(context.item_type, owner_id=context.account.id) return dext_views.AjaxOk(content={'prices': prices, 'owner_prices': owner_prices})
def api_show(context): master_hero = heroes_logic.load_hero(account_id=context.master_account.id) return dext_views.AjaxOk(content=logic.get_account_info(context.master_account, master_hero))
def api_show(context): u''' Подробная информация о конкретном городе - **адрес:** /game/places/<place>/api/show - **http-метод:** GET - **версии:** 2.0 - **параметры:** * URL place — идентификатор города - **возможные ошибки**: нет **Это экспериментальный метод, при появлении новой версии не гарантируется работоспособность предыдущей!** При завершении операции возвращается следующая информация: { "id": <целое число>, // идентификатор города "name": "строка", // название города "frontier": true|false, // является ли город фронтиром "new_for": <timestamp>, // время, до которого город считается новым "updated_at": <timestamp>, // время последнего обновления информации "description": "строка", // описание города "position": {"x": <целое число>, "y": <целое число>}, // координаты города "politic_power": <politic_power>, // политическое влияние города "persons": <persons_info>, // Мастера "attributes": <attributes_info>, // все параметры города "demographics": <demographics_info>, // расовый состав "bills": <bills_info>, // действующие законы "habits": <habits_info>, // черты города "chronicle": <chronicle_info>, // последние записи в летописи "accounts": <accounts_info>, // краткая дополнительная информация об игроках, связанных с городом "clans": <clans_info> // краткая дополнительная информация о кланах, связанных с городом } <politic_power> = { "power": { "inner": { "value": <дробное число>, // суммарное влияние ближнего круга "fraction": <дробное число> }, // доля среди остальных городов // (Фронтир и Ядро считаются отдельно) "outer": { "value": <дробное число>, // суммарное влияние «толпы» "fraction": <дробное число> }, // доля среди остальных городов // (Фронтир и Ядро считаются отдельно) "fraction": <дробное число> // доля общего влияния среди остальных городов //(Фронтир и Ядро считаются отдельно) }, "heroes": { // влияющие на город герои (ближний круг и кандидаты в него) "positive": {"<целое число>": <дробное число>}, // позитивное влияние <идентификатор героя, принесённое влияние> "negative": {"<целое число>": <дробное число>}, // негативное влияние <идентификатор героя, принесённое влияние> } } <persons_info> = [ { "id": <целое число>, // идентификатор Мастера "name": "строка", // имя "gender": <целое число>, // пол "race": <целое число>, // раса "type": <целое число>, // профессия "next_move_available_in": <дробное число>, // количество секунда до момента, когда Мастер может переехать в другой город "politic_power_fraction": <дробное число>, // доля влияния в городе "building": <целое число>|null, // идентификатор здания Мастера, если оно есть "personality": { // характер "cosmetic": <целое число>, // идентификатор косметической особенности характера "practical": <целое число> // идентификатор практической особенности характера } }, … ] <attributes_info> = { // информация о всех параметрах города "effects": [ // эффекты, действующие на город { "name": "<строка>", // название эффекта "attribute": <целое число>, // на какой аттрибут влияет "value": <целое>|<дробное>|"<строка>"|null // значение, null, если значение комплексное и пока не сериализуется в API }, ... ], "attributes": [ // итоговые значения аттрибутов { "id": <целое число>, // идентификатор аттрибута "value": <целое>|<дробное>|"<строка>"|null // значение, null, если значение комплексное и пока не сериализуется в API } ] } <demographics_info> = [ { "race": <целое число>, // раса "percents": <дробное число>, // текущая доля (от 0 до 1) "delta": <дробное число>, // изменение в день "persons": <дробное число>}, // влияние Мастеров (от 0 до 1) … ] <bills_info> = [ { "id": <целое число>, // идентификатор закона "caption": "строка", // название закона "properties": ["строка", …] }, // перечень описаний эффектов закона на город … ] <habits_info> = { // информация о каждой черте города в формате "идентификатор черты": {информация о черте} "<целое число>": {"interval": <целое число>, // идентификатор текущего «уровня» черты "value": <дробное число>, // текущее абсолютное значенеи черты "delta": <дробное число>, // величина изменения черты за один час "positive_points": <дробное число>, // суммарное позитивное влияние героев на черту города "negative_points": <дробное число> }, // суммарное негативное влияние героев на черту города … } <chronicle_info> = [("строка", "строка", "строка"), …] // последние записи из летописи о городе в формате ("короткая дата", "длинная дата", "текст") <accounts_info> = { "<целое число>": { // идентификатор игрока "id": <целое число>, // идентификатор игрока "name": "строка", // ник "hero": { // краткая информация о герое "id": <целое число>, // идентификатор "name": "строка", // имя "race": <целое число>, // раса "gender": <целое число>, // пол "level": <целое число> }, // уровень "clan": <целое число>|null // идентификатор клана }, … } <clans_info> = { "<целое число>": { // идентификатор клана "id": <целое число>, // идентификатор клана "abbr": "строка", // аббревиатура "name": "строка"}, // полное название … } ''' return dext_views.AjaxOk(content=info.place_info(context.place))
def api_new_messages(context): return dext_views.AjaxOk( content={'number': tt_api.new_messages_number(context.account.id)})
def next_turn(context): environment.workers.supervisor.cmd_next_turn() return dext_views.AjaxOk()
def give_award(context): AwardPrototype.create(description=context.form.c.description, type=context.form.c.type, account=context.master_account) return dext_views.AjaxOk()