示例#1
0
def skip_flight(self, params):
    """ params: {"flight_id": int, "flight_time": int, "az_damage": dict/int} """
    flight = self.db.fetchRow("select * from flights where id=:flight_id",
                              params)
    if flight['status'] != 'prepare':
        return api_fail(
            f"Полет находится в статусе {flight['status']} и не может быть пропущен"
        )
    build = get_build_data(self, params)
    # Все нормально - можем фрахтовать
    node_ids = [item['node_id'] for item in build.values()]
    # "Возвращаем" полет
    self.db.query("update flights set status='returned' where id=:flight_id",
                  params,
                  need_commit=True)
    # Фрахтуем узлы
    if node_ids:
        self.db.query("update nodes set status='free' where id in (" +
                      ", ".join(map(str, node_ids)) + ")",
                      None,
                      need_commit=True)
        # Выдаем компаниям KPI за фрахт узлов
        kpi_insert = [{
            "company": item['company'],
            "node_id": item['node_id'],
            "reason": "фрахт",
            "amount": 5
        } for item in build.values()]
        self.db.insert("kpi_changes", kpi_insert)
    logger.info("Полет {flight_id} пропущен".format(**params))
    return api_ok()
示例#2
0
def mcc_add_flight(self, params):
    """ params = {"departure": "2018-08-16 15:00:00", "dock": 2, "company": "pre"} """
    params['flight_id'] = self.db.insert('flights', params)
    logger.info(
        "Создан полет: отбытие {departure}, док {dock}, компания {pre}".format(
            **params))
    return api_ok(flight=params)
示例#3
0
def unload_luggage(self, params):
    """ params = {flight_id: int, code: "beacon"/"mine"/"module",
        <company>: str (только для шахт), <planet_id>: str (только для модулей) }"""
    if 'company' in params and params.get('code') != 'mine':
        del (params['company'])
    if 'planet_id' in params and params.get('code') != 'module':
        del (params['planet_id'])
    if not params.get('planet_id') and params.get('code') == 'module':
        return api_fail(
            "Для выгрузки модуля необходимо указать код планеты высадки!")
    if 'company' not in params and params.get('code') == 'mine':
        return api_fail(
            "Для выгрузки шахты необходимо указать компанию-владельца!")

    where = self.db.construct_where(params)
    sql = "select * from flight_luggage where " + where
    # Проверяем, есть ли такой груз
    row = self.db.fetchRow(sql, params)
    if not row:
        return api_fail("Такого груза нет на борту")
    if int(row['amount']) == 1:
        self.db.query("delete from flight_luggage where " + where,
                      params,
                      need_commit=True)
    else:
        self.db.query("update flight_luggage set amount = amount-1 where " +
                      where,
                      params,
                      need_commit=True)
    return api_ok()
示例#4
0
def mcc_remove(self, params):
    """ params = {"flight_id": 1, "user_id": 2} """
    deleted = self.db.query(
        "delete from flight_crews where flight_id = :flight_id and user_id = :user_id",
        params,
        need_commit=True)
    return api_ok(deleted=self.db.cursor.rowcount)
示例#5
0
文件: sync.py 项目: Hyyudu/mgl_api
def set_build_correction(self, params):
    """ params: {flight_id: int, node_type_code: str, correction: str}"""
    existing = self.db.fetchAll(
        """
    select * from builds where flight_id = :flight_id""", params,
        'node_type_code')
    if not existing:
        return api_fail(
            "Полет {flight_id) не существует, либо для него не зарезервировано ни одного узла!"
            .format(**params))
    flight = self.db.fetchRow("select * from flights where id=:flight_id",
                              params)
    if flight.get('status') == 'freight':
        return api_fail(
            "Ваш полет уже зафрахтован. Дальнейшая синхронизация невозможна")
    update_row = existing.get(params['node_type_code'])
    if not update_row:
        return api_fail(
            "Для полета не зарезервирован узел {node_type_code}".format(
                **params))
    update_row['correction_func'] = params['correction']
    update_row['correction'] = get_func_vector(params['correction'])
    update_row['total'] = xor([update_row['vector'], update_row['correction']])
    update_row['params'] = calc_node_params_with_desync(
        update_row['total'], node_id=update_row['node_id'])
    update_row['params_json'] = json.dumps(update_row['params'])
    update_row['slots'] = count_elements_for_functext(params['correction'])
    update_row['slots_json'] = json.dumps(update_row['slots'])
    if update_row['slots_json'] == 'null':
        update_row['slots_json'] = '{}'
    self.db.update(
        'builds', update_row,
        'flight_id = :flight_id and node_type_code=:node_type_code')
    del (params['correction'])
    return api_ok(node_sync=get_build_data(self, params))
示例#6
0
文件: tech.py 项目: Hyyudu/mgl_api
def create_tech(self, params):
    """ params = {name: str, description: str, level: int, is_available: 0/1, point_cost: {str: float},
    effects: [ {node_code: str, parameter_code: str, value: float},], inventors: [str] }"""
    tech_id = self.db.insert('technologies', params)
    point_costs = [
        {"tech_id": tech_id,
         "resource_code": key,
         "amount": value}
        for key, value in params['point_cost'].items()
    ]
    self.db.insert('tech_point_cost', point_costs)
    tech_inventors = [
        {"tech_id": tech_id, "company": company}
        for company in params.get("inventors", [])
    ]

    self.db.insert('tech_inventors', tech_inventors)

    tech_effects = [
        {**{"tech_id": tech_id}, **effect}
        for effect in params['effects']
    ]
    self.db.insert('tech_effects', tech_effects)
    params['id'] = tech_id
    return api_ok(tech=params)
示例#7
0
def decomm_node(self, params):
    """ params={node_id: int, is_auto: 0/1, reason: str} """
    node = self.db.fetchRow(
        """select m.company, n.az_level, n.status
        from nodes n
        join models m on m.id = n.model_id
        where n.id=:node_id""", params)
    if node['status'] in ['decomm', 'lost']:
        return api_fail(
            "Узел имеет статус {status} и уже не может быть списан".format(
                **node))
    self.db.query("update nodes set status='decomm' where id=:node_id",
                  params,
                  need_commit=True)
    if not params.get('is_auto'):

        self.db.insert(
            "kpi_changes", {
                "company": node['company'],
                "reason": "Списание узла вручную",
                "node_id": params['node_id'],
                'amount': -15
            })
    stop_pump(self, {"section": "nodes", "entity_id": params['node_id']})
    if params.get('is_auto'):
        params[
            'reason'] = f"Автоматическое списание, уровень АЗ {node['az_level']}"
    logger.info("Списан узел {node_id}, причина: {reason}".format(**params))
    return api_ok(reason=params.get('reason', ''))
示例#8
0
def mcc_assign_flight(self, params):
    """ params = {"flight_id": int, "company": mat/mst/gd/pre/kkg/ideo} """
    company = params.get('company', '')
    if company not in ('mat', 'mst', 'gd', 'pre', 'kkg', 'ideo'):
        return api_fail("Неверный код компании")
    params['id'] = params['flight_id']
    self.db.update('flights', params, "id=:id")
    return api_ok(updated=self.db.affected_rows())
示例#9
0
def mcc_set_crew(self, params):
    """ params = {"flight_id": 1, "role": "pilot", "user_id": 2} """
    self.db.query("""delete from flight_crews 
        where flight_id = :flight_id and (role=:role or user_id=:user_id)""",
                  params,
                  need_commit=True)
    self.db.insert('flight_crews', params)
    return api_ok()
示例#10
0
def boost_use(self, params):
    """ params = {"password": str} """
    boost = self.db.fetchRow('select code, used_datetime from boosts where password=:password', params)
    if not boost:
        return api_fail("Пароль неверен")
    if boost['used_datetime']:
        return api_fail("Этот буст уже был использован")
    self.db.query("update boosts set used_datetime=now() where password=:password", params)
    return api_ok()
示例#11
0
def mcc_set_all_crew(self, params):
    """ params = {"flight_id": int, "crew": [{"role": "pilot", "user_id": 1}, {"role": "radist", "user_id": 2}] }"""
    if not self.db.fetchRow('select * from flights where id=:flight_id',
                            params):
        return api_fail("Полет с указанным номером не существует")
    self.db.query("delete from flight_crews where flight_id=:flight_id",
                  params,
                  need_commit=True)
    if params['crew']:
        for item in params['crew']:
            item['flight_id'] = params['flight_id']
        self.db.insert('flight_crews', params['crew'])
    return api_ok(crew=params['crew'])
示例#12
0
def mcc_add_passenger(self, params):
    """ params = {"flight_id": 1, "user_id": 2} """
    cnt = self.db.fetchOne(
        'select count(*) from flight_crews where flight_id=:flight_id and role="_other"',
        params)
    if cnt >= 5:
        return api_fail("В полет разрешается брать не более 5 пассажиров!")
    params['role'] = "_other"
    self.db.query("""delete from flight_crews 
        where flight_id = :flight_id and user_id=:user_id""",
                  params,
                  need_commit=True)
    self.db.insert('flight_crews', params)
    return api_ok()
示例#13
0
def flight_died(self, params):
    """ params = {flight_id: int} """
    # Находим все узлы того полета
    node_ids = self.db.fetchColumn(
        "select node_id from builds where flight_id=:flight_id", params)
    nodelist = "(" + ", ".join(node_ids) + ")"
    # Ставим всем узлам статус "утерян"
    self.db.query(
        f"update nodes set status_code='lost' where id in {nodelist}",
        None,
        need_commit=True)
    # Отключаем их насосы в экономике
    self.db.query(
        f"update pumps set date_end = Now() where section='nodes' and entity_id in {nodelist}",
        need_commit=True)
    return api_ok()
示例#14
0
def add_node_upkeep_pump(self, node_id=None, model=None):
    if not model:
        model = self.db.fetchRow("""select m.id, m.name, m.company
    from models m join nodes n on m.id = n.model_id
    where n.id = :node_id""", {"node_id": node_id})
    upkeep_price = get_model_upkeep_price(self, {"model_id": model['id']})
    insufficient = get_insufficient_for_node(company=model['company'], model_id=model['id'], upkeep_price=upkeep_price)
    if insufficient:
        return api_fail("Вашего дохода не хватает для создания узла: " + dict2str(insufficient))

    pump = {
        "company": model['company'],
        "section": "nodes",
        "entity_id": node_id,
        "comment": "Поддержка узла {} модели {}".format(node_id, model['name']),
        "is_income": 0,
        "resources": upkeep_price
    }
    add_pump(self, pump)
    return api_ok(pump=pump)
示例#15
0
def load_luggage(self, params):
    """ params = {flight_id: int, code: "beacon"/"mine"/"module",
        <company>: str (только для шахт), <planet_id>: str (только для модулей) }"""
    if 'company' in params and params.get('code') != 'mine':
        del (params['company'])
    if 'planet_id' in params and params.get('code') != 'module':
        del (params['planet_id'])
    if not params.get('planet_id') and params.get('code') == 'module':
        return api_fail(
            "Для загрузки модуля необходимо указать код планеты высадки!")
    if 'company' not in params and params.get('code') == 'mine':
        return api_fail(
            "Для загрузки шахты необходимо указать компанию-владельца!")

    where = self.db.construct_where(params)
    # Пытаемся добавить к существующим
    update_sql = 'update flight_luggage set amount=amount +1 where ' + where
    self.db.query(update_sql, params, need_commit=True)
    if self.db.affected_rows() == 0:
        self.db.insert('flight_luggage', params)
    return api_ok()
示例#16
0
def flight_returned(self, params):
    """ params = {
"flight_id": int,
"flight_time": int, // время полета в секундах
"az_damage": {
    "march_engine": 32.5,
    "warp_engine": 12.9,
} / float
}"""
    self.db.query("update flights set status='returned' where id = :flight_id",
                  params,
                  need_commit=True)
    # Находим все узлы того полета
    nodes = self.db.fetchDict(
        "select node_type_code, node_id from builds where flight_id=:flight_id",
        params, 'node_type_code', 'node_id')
    for node_type_code, node_id in nodes.items():
        if node_type_code == 'hull':
            az_damage = roundTo(params['flight_time'] / (5 * 60))
        else:
            if isinstance(params['az_damage'], dict):
                az_damage = roundTo(
                    params['az_damage'].get(node_type_code, 0) +
                    params['flight_time'] / (8 * 60))
            else:
                az_damage = roundTo(params['az_damage'] +
                                    params['flight_time'] / (8 * 60))
        self.db.query(
            f"update nodes set status='free', az_level = az_level - {az_damage} where id={node_id}",
            None,
            need_commit=True)
    logger.info("Полет {flight_id} вернулся".format(**params))
    nodes_to_decomm = self.db.fetchColumn(
        "select id from nodes where az_level  <= 15 and status='free'")
    for node_id in nodes_to_decomm:
        decomm_node(self, {"node_id": node_id, "is_auto": 1})
    return api_ok(nodes_to_decomm=nodes_to_decomm)
示例#17
0
def set_build_correction(self, params):
    """ params: {flight_id: int, node_type_code: str, correction: str}"""
    existing = self.db.fetchAll(
        """
    select * from builds where flight_id = :flight_id""", params,
        'node_type_code')
    if not existing:
        return api_fail(
            "Полет {flight_id) не существует, либо для него не зарезервировано ни одного узла!"
            .format(**params))
    update_row = existing.get(params['node_type_code'])
    if not update_row:
        return api_fail(
            "Для полета не зарезервирован узел {node_type_code}".format(
                **params))
    update_row['correction_func'] = params['correction']
    update_row['correction'] = get_func_vector(params['correction'])
    update_row['total'] = xor([update_row['vector'], update_row['correction']])
    update_row = get_node_params_with_desync(update_row['total'],
                                             node_id=update_row['node_id'])
    self.db.update(
        'bulids', update_row,
        'flight_id = :flight_id and node_type_code=:node_type_code')
    return api_ok(node_sync=update_row)
示例#18
0
def stop_pump(self, params):
    """ params {pump_id: int} """
    self.db.query("update pumps set date_end=Now() where id=:pump_id",
                  params,
                  need_commit=True)
    return api_ok()
示例#19
0
def stop_pump(self, params):
    """ params {<id>: int, <company>: str, <section>: mines/nodes/models/crises/markets, <entity_id>: int/str} """
    self.db.query("update pumps set date_end=Now() where "+self.db.construct_where(params), params, need_commit=True)
    return api_ok()
示例#20
0
文件: tech.py 项目: Hyyudu/mgl_api
def develop_model(self, params):
    """ params = {
        "node_type_code": "radar",
        "company": "mat",
        "size": "large",
        "tech_balls": {"1": 10, "2": 5},
        "name": "Азаза",
        "description": "",
        "password": ""
    }
    """
    existing_model_name = self.db.fetchRow("select * from models where name=:name", params)
    if existing_model_name:
        return api_fail("Модель с названием {name} уже создана".format(**params))
    # Читаем используемые технологии
    techs = read_techs(self, params)
    # Чистим неиспользуемые техи
    params['tech_balls'] = {
        int(key): value
        for key, value in params['tech_balls'].items()
        if int(key) in techs.keys()
    }
    # Считаем, сколько апкипа жрет модель
    model_upkeep = calc_model_upkeep(self, params['tech_balls'])
    # проверяем, хватает ли доходов
    insufficient = get_insufficient_for_both(company=params['company'], upkeep_price=model_upkeep)
    if insufficient:
        return api_fail("Для создания модели и стартового узла по этой модели вам не хватает ресурсов: "+
                        dict2str(insufficient))


    # Вычисляем параметры
    model_params = calc_model_params(self, params)
    # Находим цену в KPI
    model_kpi_price = sum([
        ball * techs.get(tech_id, {}).get('level', 0) ** 2
        for tech_id, ball in params['tech_balls'].items()
    ])
    model_level = get_model_level_by_technologies([
        [techs[key].get('level'), value]
        for key, value in params['tech_balls'].items()
    ])

    model_data = add_model(self, {
        "name": params['name'],
        "description": params.get("description", ''),
        "level": model_level,
        "kpi_price": model_kpi_price,
        "size": params['size'],
        "node_type_code": params['node_type_code'],
        "company": params['company'],
        'params': model_params,
        "upkeep": model_upkeep,
    })
    model_id = model_data['data']['id']
    # Создаем временный насос
    model_pump = add_pump(self, {
        "company": params['company'],
        'section': 'models',
        'entity_id': model_id,
        'comment': f'Разработка модели {model_id} {params["name"]}',
        "is_income": 0,
        "resources": {code: value / 2 for code, value in model_upkeep.items()}
    })
    # Устанавливаем насосу время окончания
    self.db.query(f"""update pumps set date_end = Now() + interval {MODEL_WOW_PERIOD_HOURS} hour
            where id=:id""", model_pump['data'], need_commit=True)
    # Создаем стартовый узел
    if not params.get('password'):
        params['password'] = str(randint(1000, 9999)) if params['company'] != 'pre' else ''
    create_node(self, {"model_id": model_id, "password": params['password']})
    return api_ok(params=params)
示例#21
0
def freight_flight(self, params):
    """ params {flight_id: int} """
    flight = self.db.fetchRow("select * from flights where id=:flight_id",
                              params)
    if flight['status'] == 'freight':
        return api_fail(f"Ваш полет уже зафрахтован")
    if flight['status'] != 'prepare':
        return api_fail(
            f"Полет находится в статусе {flight['status']} и не может быть зафрахтован"
        )
    build = get_build_data(self, params)

    # Проверить, что корабль состоит из всех нужных узлов.
    nodes_not_reserved = set(NODE_NAMES.keys()) - set(build.keys())
    if nodes_not_reserved:
        return api_fail(
            "Невозможно совершить фрахт. В корабле не хватает следующих узлов: "
            + ", ".join([NODE_NAMES[item] for item in nodes_not_reserved]))

    # проверить, что общий объем неотрицательный
    hull_volume = build['hull']['params']['volume']['value']
    inner_nodes_volume = sum([
        item['params']['volume']['value'] for item in build.values()
        if item['node_type_code'] != 'hull'
    ])
    luggage_volume = self.db.fetchOne(
        """
    select sum(fl.amount* vl.volume)
    from flight_luggage fl 
    join v_luggages vl on fl.code = vl.code
    and (fl.company = vl.company or (fl.company is null and vl.company is null))
    where fl.flight_id = :flight_id""", params) or 0
    if hull_volume - inner_nodes_volume - luggage_volume < 0:
        return api_fail(
            f"Внутренний объем вашего корпуса {hull_volume}. Его недостаточно для размещения всех узлов "
            +
            f"(суммарный объем {inner_nodes_volume}) и багажа (суммарный объем {luggage_volume})"
        )

    # Проверить, что всех слотов синхронизации хватает
    slots = defaultdict(int)
    for row in build.values():
        for slot_type, qty in row['slots'].items():
            slots[slot_type] += qty * (1 if row['node_type_code'] == 'hull'
                                       else -1)
    not_enough_slots = {key: val for key, val in slots.items() if val < 0}
    if not_enough_slots:
        return api_fail(
            "В корпусе недостаточно слотов для выбранных инженером формул синхронизации. "
            + "Недостающие слоты: " + dict2str(not_enough_slots))

    # Все нормально - можем фрахтовать
    node_ids = [item['node_id'] for item in build.values()]
    # Фрахтуем полет
    self.db.query("update flights set status='freight' where id=:flight_id",
                  params,
                  need_commit=True)
    # Фрахтуем узлы
    self.db.query("update nodes set status='freight' where id in (" +
                  ", ".join(map(str, node_ids)) + ")",
                  None,
                  need_commit=True)
    # Выдаем компаниям KPI за фрахт узлов
    kpi_insert = [{
        "company": item['company'],
        "node_id": item['node_id'],
        "reason": "фрахт",
        "amount": 5
    } for item in build.values()]
    self.db.insert("kpi_changes", kpi_insert)

    # Формируем инфу по щитам для CouchDb
    dock = flight['dock']
    shield_value = round(
        build['shields']['params']['desinfect_level']['value'])
    url = f"https://api.alice.magellan2018.ru/ships/set_shields/{dock}/{shield_value}"
    requests.get(url,
                 auth=HTTPBasicAuth(os.environ['ADMIN_USER'],
                                    os.environ['ADMIN_PASSWORD']))

    return api_ok()
示例#22
0
def mcc_add_flight(self, params):
    """ params = {"departure": "2018-08-16 15:00:00", "dock": 2, "company": "pre"} """
    params['flight_id'] = self.db.insert('flights', params)
    return api_ok(flight=params)