def get_movable_area_by_division_id(division_id, col, row):
    """
    部隊IDから移動可能なエリアを取得
    DBエラー、または部隊IDの部隊がなければExceptionをスロー
    :param division_id:
    :param col: プレイヤーのcol
    :param row: プレイヤーのrow
    :return: [{col, row, time(速度補正)}]
    """

    result = None
    try:
        db = DBSingleton()

        # 部隊の兵科と座標
        from lib.DB.division_controller import get_division_info
        division = get_division_info(division_id)

        # 兵科の情報
        from lib.DB.branch_controller import get_branch_info
        branch = get_branch_info(division["branch_id"])

        # 隣接する座標を計算
        adjacent_area = get_adjacent_area(col, row, 1)

        # エリアの地形取得
        where = ""
        for hex in adjacent_area:
            where += " (col = " + str(hex["col"]) + " and row = " + str(
                hex["row"]) + ") or"
        where = where[:-3]
        terrian_type = db.select("col",
                                 "row",
                                 "type",
                                 table="hex_grid",
                                 where=where)

        # 兵科速度 * 地形補正から所要時間を計算
        result = []
        for hex in terrian_type:
            result.append({
                "col": hex["col"],
                "row": hex["row"],
                "time": branch["speed"] * branch[hex["type"]]
            })

    except DBError as e:
        logging.error(e.message)
        raise Exception("DBエラー")
        return False

    except Exception as e:
        raise e

    return result
示例#2
0
def request_hexinfo(_cls, _self, _data):
    """ヘックスの情報を取得"""

    payload = {"event": "response_hexinfo", "data": {}}

    data = {"hex_info": {}}

    # 取得しているプレイヤーの情報
    self_id = _self.get_secure_cookie("user_id").decode('utf-8')
    self_info = get_playerinfo_by_id(self_id)

    # ヘックスの情報
    hex_info = get_hexinfo(_data["col"], _data["row"])
    if hex_info == None:
        logging.error("failed to retrieve hex_info : " + str(data["col"]) +
                      " , " + str(data["row"]))
        _cls.send_error(_self, "エラーでキャンセルされた")

    data["hex_info"]["type"] = hex_info["type"]
    if hex_info[self_info["visibility"]] > 0:
        # 可視範囲ならより詳細な情報取得
        data["hex_info"]["food"] = hex_info["food"]
        data["hex_info"]["money"] = hex_info["money"]

    # 在中プレイヤーの情報
    other_player = get_players_by_visibility(self_info["visibility"], True,
                                             [{
                                                 "col": _data["col"],
                                                 "row": _data["row"]
                                             }])
    if len(other_player) != 0:

        # プレイヤー情報
        data["player_info"] = {}
        other_player = other_player[0]
        data["player_info"]["player_name"] = other_player["user_name"]
        country_id = other_player["country_id"]
        country_info = get_countryinfo_by_id(other_player["country_id"])
        data["player_info"]["country_name"] = country_info["country_name"]

    # 部隊情報
    division_info = get_division_info_by_colrow(_data["col"], _data["row"])
    if division_info:
        branch_info = get_branch_info(division_info["branch_id"])
        data["division_info"] = {}
        data["division_info"]["division_name"] = division_info["division_name"]
        data["division_info"]["status"] = division_info["status"]
        data["division_info"]["level"] = division_info["level"]
        data["division_info"]["quantity"] = division_info["quantity"]
        data["division_info"]["branch_name"] = branch_info["branch_name"]

    payload["data"] = data
    _self.send_you(payload)
def update_visible_area(visibility, division_id, switch):
    """
    部隊の視界内のヘックスの可視性を変更
    :param visibility: 可視権
    :param division_id: 部隊ID
    :param switch: True ? 可算 : 減算
    :return: 成功 ? True : False
    """

    try:

        # 部隊の情報
        from lib.DB.division_controller import get_division_info
        division = get_division_info(division_id)

        # 兵科の情報
        from lib.DB.branch_controller import get_branch_info
        branch = get_branch_info(division["branch_id"])

        # 現在の部隊の視界
        visible_area = get_adjacent_area(division["col"], division["row"],
                                         branch["visible_range"])
        visible_area.append({"col": division["col"], "row": division["row"]})

        # 更新
        if switch: switch = str("+")
        else: switch = str("-")

        where = "where "
        for hex in visible_area:
            where = where + "(col=" + str(hex["col"]) + " and row=" + str(
                hex["row"]) + ") or"
        where = where[:-3]

        query = "update hex_grid set " + \
                visibility + " = " + visibility + " " + switch + " 1 " + where
        db = DBSingleton()
        db.exec(query)

        print("update p6")
    except DBError as e:
        logging.error(e.message, detailed_error.get_error())
        return False

    except Exception as e:
        logging.error(e, detailed_error.get_error())
        return False

    return True
示例#4
0
def ask_move(_cls, _self, data):
    """進軍可能な進路を問い合わせに対する応答"""

    payload = {"event" : "response_ask_move",
               "data" : {}}
    try:

        db = DBSingleton()
        user_id = _self.get_secure_cookie("user_id").decode('utf-8')

        # プレイヤーの状態
        player = get_playerinfo_by_id(user_id)

        # プレイヤーが待機中でないと移動できない
        if player["status"] != "ready":
            payload["data"] = {"response" : "deny",
                                "reason"   : "行動中"}
            _self.send_you(payload)
            return True

        # 配下の師団がセットされていないと移動できない
        if not player["division_id"]:
            payload["data"] = {"response" : "deny",
                                "reason"   : "配下の部隊がセットされていない"}
            _self.send_you(payload)
            return True

        # 配下の師団取得
        division = get_division_info(player["division_id"])

        # 師団の兵科情報取得
        branch_info = get_branch_info(division["branch_id"])

        # 師団がヘックスに移動可能かどうか
        ajacent_area = get_adjacent_area(division["col"], division["row"])
        isMovable = False
        for ajacent_hex in ajacent_area:
            if ajacent_hex["col"] == data["col"] and ajacent_hex["row"] == data["row"]:
                isMovable = True
                break
        if not isMovable:
            payload["data"] = {"response" : "deny",
                                "reason" : "移動可能半径ではない"}
            _self.send_you(payload)
            return True

        # ゲームレベルから設定値を取得
        gm = GameMain()
        op_food_lv = gm.get_affair().get_op_food_lv()
        op_money_lv = gm.get_affair().get_op_money_lv()
        op_speed_lv = gm.get_affair().get_op_speed_lv()


        # 運用に必要な食糧と金 : 師団規模 * 兵科固定値 * ゲームレベル
        food_needed = division["quantity"] * branch_info["op_food"] * op_food_lv
        money_needed = division["quantity"] * branch_info["op_money"] * op_money_lv

        # 資金と食糧、それぞれ足りなければ移動不可
        if division["food"] < food_needed:
            payload["data"] = {"response" : "deny",
                                "reason"   : ("部隊の運用食糧が足りない",
                                               "部隊の保持食糧 : " + str(division["food"]) ,
                                               "必要な食糧 = 師団規模(" + str(division["quantity"]),
                                               ")×兵科補正(" + str(branch_info["op_food"]) ,
                                               ")×情勢補正(" + str(op_food_lv) + ") = " + str(food_needed))}
            _self.send_you(payload)
            return True

        elif division["money"] < money_needed:
            payload["data"] = {"response" : "deny",
                                "reason"   : ("部隊の運用資金が足りない",
                                               "部隊の保持資金 : " + str(division["money"]),
                                               "必要な資金 = 師団規模(" + str(division["quantity"]),
                                               ")×兵科補正(" + str(branch_info["op_money"]),
                                               ")×情勢補正(" + str(op_money_lv) + ") = " + str(money_needed))}
            _self.send_you(payload)
            return True

        # ヘックス情報
        hex_info = get_hexinfo(data["col"], data["row"])

        # 地形情報
        terrian_info = get_terrian_info(hex_info["type"])

        # 所要時間 = 地形補正 * 兵科速度 * ゲーム速度
        required_time = terrian_info[division["branch_id"]] * branch_info["speed"] * op_speed_lv

        payload["data"]["response"] = "accept"
        payload["data"]["food"] = food_needed
        payload["data"]["money"] = money_needed
        payload["data"]["required_time"] = int(required_time)
        _self.send_you(payload)
        return True

    except DBError as e:
        logging.error("move_query失敗" + e.message)
        _self.send_error("サーバーエラー : 進軍可能な範囲の問い合わせに失敗。行動はキャンセルされた")
        return False

    except Exception as e:
        logging.error(e)
        payload["data"] = {"response" : "deny",
                            "reason"   : "サーバーエラー"}
        _self.send_error("サーバーエラー : ハンドルされていないエラー。行動はキャンセルされた")
        return False

    assert False
示例#5
0
def request_move(_cls, _self, data):
    """
    行軍イベントをセットする
    :param _cls: BJSocketHandlerのクラス
    :param _self: BJSocketHandlerのインスタンス
    :param data: クライアントから受信したデータ
    :return:
    """

    user_id = _self.get_secure_cookie("user_id").decode('utf-8')
    payload = {"event" : "response_request_move" ,
               "data"  : {}}



    try:

        """
        move_queryの焼き増しな部分があるが、queryとrequestの時間差または不正防止のため
        再度移動可能かどうか調べる
        """

        # 目的地
        dest_col = data["col"]
        dest_row = data["row"]

        # プレイヤーの状態
        user_id = _self.get_secure_cookie("user_id").decode('utf-8')
        player = get_playerinfo_by_id(user_id)

        # プレイヤーが待機中でないと移動できない
        if player["status"] != "ready":

            payload["data"] = {"response" : "deny",
                                "reason"   : "行動中"}
            _self.send_you(payload)
            return

        # 配下の部隊の状態
        division = get_division_info(player["division_id"])

        # 部隊がセットされていないと移動できない
        if not division:
            payload["data"] = {"response" : "deny",
                                "reason"   : "配下の師団がセットされていない"}
            _self.send_you(payload)

        # 部隊の移動半径内でないと移動できない
        movable_area = get_movable_area_by_division_id(division["division_id"], player["col"], player["row"])

        required_time = False # 所要時間
        for hex in movable_area:
            if hex["col"] == dest_col and hex["row"] == dest_row:
                required_time = hex["time"]

        if not required_time:
            payload["data"] = {"response" : "deny",
                               "reason"   :  "[" + str(dest_col) + "," + str(dest_row) + "]は移動可能半径外"}
            _cls.send_player(user_id, payload)

        # 師団の兵科情報取得
        branch_info = get_branch_info(division["branch_id"])

        # ゲームレベルから設定値を取得
        gm = GameMain()
        op_food_lv = gm.get_affair().get_op_food_lv()
        op_money_lv = gm.get_affair().get_op_money_lv()
        op_speed_lv = gm.get_affair().get_op_speed_lv()

        # 運用に必要な食糧と金 : 師団規模 * 兵科固定値 * ゲームレベル
        food_needed = division["quantity"] * branch_info["op_food"] * op_food_lv
        money_needed = division["quantity"] * branch_info["op_money"] * op_money_lv

        # 資金と食糧、それぞれ足りなければ移動不可
        if division["food"] < food_needed:
            payload["data"] = {"response" : "deny",
                                "reason"   : "部隊の運用食糧が足りない。<br>" +
                                             "部隊の保持食糧 : " + str(division["food"]) + "<br>" +
                                             "必要な食糧 = 師団規模(" + division["quantity"] +
                                            ")×兵科補正(" + str(branch_info["op_food"]) +
                                             ")×情勢補正(" + str(op_food_lv) + ") = " + str(food_needed)}
            _self.send_you(payload)
            return False

        elif division["money"] < money_needed:
            payload["data"] = {"response" : "deny",
                                "reason"   : "部隊の運用資金が足りない。<br>" +
                                             "部隊の保持資金 : " + str(division["money"]) + "<br>" +
                                             "必要な資金 = 師団規模(" + division["quantity"] +
                                            ")×兵科補正(" + str(branch_info["op_money"]) +
                                             ")×情勢補正(" + str(op_money_lv) + ") = " + str(money_needed)}
            _self.send_you(payload)
            return False

        """
       チェックが終わったのでプレイヤー情報等を更新し、行軍イベントをセットする
        """

        # 到着予定時刻計算
        required_time = required_time * op_speed_lv # ゲームレベル適用
        current_time = BJTime.get_time_now()
        arrival_time = BJTime.add_time(current_time, required_time)

        # TODO: チェックと次の処理の間に状態が変更される可能性がある

        # 行軍のイベントレコードを作成
        event_record = EventMove.create_recode(user_id=player["user_id"],
                                               division_id=division["division_id"],
                                               dest_col=dest_col,
                                               dest_row=dest_row,
                                               datetime=arrival_time)
        # レコードの作成に失敗していれば失敗
        if event_record is None:
             payload["data"] = {"response" : "deny",
                                "reason"   : "イベントレコードの作成に失敗した。管理者に連絡して下さい。"}
             _self.send_you(payload)
             return

        # レコードをDBに登録
        add_event(event_record)

        # メインエンジンにイベントの実行時を通知
        gm = GameMain()
        gm.set_event_timestamp(arrival_time)

        # プレイヤーの状態を更新
        update_user_before_move(user_id=player["user_id"],
                                wait_untill=arrival_time)
        update_user_status(player["user_id"],"moving")

        # 部隊の状態を更新
        update_division_before_move(division_id=division["division_id"],
                                    food=food_needed,
                                    money=money_needed)
        update_division_status(division["division_id"], "moving")

        # クライアントに通知
        payload["data"] =  { "response" : "approval",
                              "arrival_time" : arrival_time.strftime("%Y-%m-%d %H:%M:%S")}

        _self.send_you(payload)
        return

    except Exception as e:
        logging.error(e)
        _self.send_error(e.message);
        return

    assert False