def init_bbs_country(_cls, _self, data):

    payload = {"event": "init_bbs_country"}
    data = []

    #DBから会議室の内容を集める
    try:
        user_id = _self.get_secure_cookie("user_id").decode('utf-8')
        db = DBSingleton()
        country = db.select("country_id",
                            table="user",
                            where="user_id=" + "\"" + str(user_id) + "\"")
        country = country[0]["country_id"]
        query = "select user.user_name, user.icon_id, bbs_country.date, bbs_country.article from user " \
                "inner join bbs_country "\
                "on user.user_id=bbs_country.user_id "\
                "where bbs_country.country_id = " + str(country) + \
                " order by bbs_country.date desc limit 20;"
        result = db.exec(query, True)

        for article in result:
            data.append({
                "name": article[0],
                "icon": article[1],
                "date": article[2].strftime("%Y-%m-%d %H:%M:%S"),
                "article": article[3]
            })

    except DBError as e:
        logging.error(u"init_bbs_country.py: 会議室の情報取得失敗。\nmessage = " + str(e))
        raise Exception("会議室の情報取得失敗")

    #送信するデータ組み立て
    payload["data"] = data
    _self.send_you(payload)
def get_unvisible_area(visibility, timestamp=None):
    """
    可視権から不可視範囲のグリッドを取得
    :param visibility:
    :param [timestamp]: オプション。この時刻オブジェクト以降に変更されたグリッドのみ取得する
    :return: list[dict[col, row, type]]
    """
    result = None
    try:
        # 可視権による条件
        where = str(visibility) + " = 0"

        # タイムスタンプによる条件
        if timestamp is not None:
            datetime = BJTime.encode_to_sql(timestamp)
            where += " and timestamp >= \"" + datetime + "\""

        db = DBSingleton()
        result = db.select("col", "row", "type", table="hex_grid", where=where)
    except DBError as e:
        logging.error(e.message)
        raise Exception("DBエラー : visibilityが" + str(visibility) +
                        u"の不可視範囲のグリッド取得失敗")
        return

    return result
def update_hex(col, row, **kargs):
    """
    ヘックスのレコードを更新
    :param col: 該当ヘックスcol
    :param row: 該当ヘックスrow
    :param kargs: {key : value, ...}
    :return: 成功 ? True : False
    """

    try:
        db = DBSingleton()

        sentence = "update hex_grid set"

        for key, value in kargs.items():
            sentence = sentence + " " + str(key) + " = \"" + str(value) + "\""

        sentence += " where col = " + str(col) + " and row = " + str(row)

        db.exec(sentence)
        return True

    except DBError as e:
        logging.error(e.message, detailed_error.get_error())
        return False
def get_own_area(country_id, timestamp=None):
    """
    領地を取得
    :param country_id:
    :return: 成功 ? area : None
    """

    try:
        db = DBSingleton()

        where = "country_id = " + str(country_id)

        # タイムスタンプによる条件
        if timestamp is not None:
            datetime = BJTime.encode_to_sql(timestamp)
            where += " and timestamp >= \"" + datetime + "\""

        result = db.select("col",
                           "row",
                           "type",
                           "country_id",
                           "food",
                           "money",
                           table="hex_grid",
                           where=where)
        if len(result) == 0:
            return None
        else:
            return result

    except DBError as e:
        logging.error(e.message, detailed_error.get_error())
        return None
Exemple #5
0
def get_division_info_by_colrow(col, row):
    try:
        db = DBSingleton()
        result = db.select(
            "division_id",  # 部隊ID
            "division_name",  # 部隊名
            "col",  # 座標
            "row",  # 座標
            "branch_id",  # 兵科ID
            "user_id",  # 所有ユーザー
            "country_id",  # 所属国
            "status",  # 状態
            "food",  # 食糧
            "money",  # 資金
            "level",  # 練度
            "quantity",  # 規模
            table="division",
            where="col=" + str(col) + " and row=" + str(row))

    except DBError as e:
        logging.error(e.message)
        raise Exception("部隊の情報取得に失敗")
        return False

    if len(result) == 0:
        return False

    return result[0]
def get_hexinfo(col, row):
    """
    :param col: hex_gridのcol
    :param row: hex_gridのrow
    :return:
    """
    try:
        db = DBSingleton()
        result = db.select("col",
                           "row",
                           "type",
                           "country_id",
                           "food",
                           "money",
                           "visibility_0",
                           "visibility_1",
                           table="hex_grid",
                           where="col=" + str(col) + " and row = " + str(row))
        if len(result) == 0:
            return None
        else:
            return result[0]

    except DBError as e:
        logging.error(e.message, detailed_error.get_error())
        return None
    except Exception as e:
        logging.error(e, detailed_error.get_error())
        return None
Exemple #7
0
def get_division_info(division_id):
    """
    部隊の情報を取得する
    DBエラーの時はDBErrorをスローする
    :param division_id: 部隊ID
    :return: 該当するIDの部隊 ? {divisionテーブルの全てのkey} : false
    """

    try:
        db = DBSingleton()
        result = db.select(
            "division_id",  # 部隊ID
            "division_name",  # 部隊名
            "col",  # 座標
            "row",  # 座標
            "branch_id",  # 兵科ID
            "user_id",  # 所有ユーザー
            "country_id",  # 所属国
            "status",  # 状態
            "food",  # 食糧
            "money",  # 資金
            "level",  # 練度
            "quantity",  # 規模
            table="division",
            where="division_id = \"" + str(division_id) + "\"")

    except DBError as e:
        logging.error(e.message)
        raise Exception("部隊の情報取得に失敗")
        return False

    if len(result) == 0:
        return False

    return result[0]
def get_userid_by_username(user_name):
    """
    ユーザー名からユーザーIDを取得
    該当のユーザー
    :param user_name:
    :return: ユーザーID
    """
    result = None
    try:
        db = DBSingleton()
        result = db.select("user_id",
                           table="user",
                           where="user_name = \"" + str(user_name) + "\"")

    except DBError as e:
        logging.error(e.message)
        raise Exception("DBエラー:ユーザー名取得失敗")
        return False

    if len(result) == 0:
        logging.error("There's no such a player in DB: user_name = " +
                      str(user_name))
        raise Exception(u"user_nameが" + str(user_name) + u"のプレイヤーは存在しない")
        return False

    return result[0]["user_id"]
def update_bbs_country(_cls, _self, data):

    payload = { "event" : "update_bbs_country"}
    send_data = None
    country = None

    try:

        #DBから最新の会議室への書き込みを取得
        user_id = _self.get_secure_cookie("user_id").decode('utf-8')
        db = DBSingleton()
        country = db.select("country_id", table="user", where="user_id=" + "\""+str(user_id) + "\"")
        country = country[0]["country_id"]
        query = "select user.user_name, user.icon_id, bbs_country.date, bbs_country.article from user " \
                "inner join bbs_country "\
                "on user.user_id=bbs_country.user_id "\
                "where bbs_country.country_id = " + str(country) + \
                " order by bbs_country.date desc limit 1;"
        result = db.exec(query, True)

        send_data= {"name" : result[0][0],
                "icon" : result[0][1],
                "date" : result[0][2].strftime("%Y-%m-%d %H:%M:%S"),
                "article" : result[0][3]}

    except DBError as e:
        logging.error(u"init_bbs_country.py: 会議室の情報取得失敗。\nmessage = " + e.message)
        raise Exception(u"会議室の情報取得失敗")

    #送信するデータ組み立て
    payload["data"] = send_data
    print(payload)
    _cls.send_member_by_country(payload, country)
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
def get_players_by_visibility(visibility, isVisible, hexes=None):
    """
    可視権から可視範囲上のプレイヤー情報を取得
    :param visibility: 可視権
    :param isVisible: true ? 可視なプレイヤー : 不可視なプレイヤー
    :param [hexes]: 指定されたグリッド [ [col, row, ...], ... ]
    :return: [{user_name, col, row, icon_id, country_id}]
    """

    print("on get_players_by_visibility")
    logger = logging.getLogger(sys._getframe().f_code.co_name)
    results = None
    try:
        db = DBSingleton()

        where = "where hex_grid." + visibility
        if isVisible:
            where += " > 0 "
        else:
            where += " = 0 "
        # ヘックスが指定されていれば条件追加
        print("hexes = ", hexes)
        if hexes is not None:
            print(hexes)
            where += "and ("
            for hex in hexes:
                where = where + " (hex_grid.col=" + str(
                    hex["col"]) + " and hex_grid.row=" + str(
                        hex["row"]) + ") or"
            where = where[:-3]
            where += ");"

        query  = "select user_name, user.col, user.row, icon_id, user.country_id from user " \
                "inner join hex_grid "\
                "on user.col=hex_grid.col and user.row=hex_grid.row " \
                + where
        results = db.exec(query, True)

    except DBError as e:
        logging.error(" message = " + e.message)
        return False

    result = []
    for player in results:
        record = {
            "user_name": player[0],
            "col": player[1],
            "row": player[2],
            "icon_id": player[3],
            "country_id": player[4]
        }
        result.append(record)
    return result
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
def update_user_before_move(user_id, wait_untill):
    """
    移動に伴うユーザー情報の更新
    :param user_id:
    :param wait_untill: 到着予定時刻を表す時刻オブジェクト
    :param status: 移動中の状態
    :return: 更新成功 ?  : Exception
    """

    try:
        db = DBSingleton()
        query = "update user set"  + \
                " wait_untill = \"" +  BJTime.encode_to_sql(wait_untill)+ "\"" \
                " where user_id = \"" + str(user_id) + "\""
        result = db.exec(query)

    except DBError as e:
        logging.error(e.message)
        raise Exception("DBエラー : 移動前のユーザー情報更新失敗")
Exemple #14
0
def move_division(division_id, dest_col, dest_row):
    """
    部隊を移動させる
    :param division_id: 部隊ID
    :param dest_col: 目的地col
    :param dest_row: 目的地row
    :return: 成功 ? True : False
    """

    try:
        db = DBSingleton()
        query = "update division set col=" + dest_col + ", row=" + dest_row
        where = " where division_id = \"" + division_id + "\""
        db.exec(query + where, False)
        return True

    except DBError as e:
        logging.error(e.message)
        return False
def move_user(user_id, dest_col, dest_row):
    """
        プレイヤーを移動させる
        :param user_id: ユーザーID
        :param dest_col: 目的地col
        :param dest_row: 目的地row
        :return: 成功 ? True : False
        """

    try:
        db = DBSingleton()
        query = "update user set col=" + dest_col + ", row=" + dest_row
        where = " where user_id = \"" + user_id + "\""
        db.exec(query + where, False)
        return True

    except DBError as e:
        logging.error(e.message)
        return False
def get_adjacent_area(col, row, _range=1):
    """
    あるヘックスからレンジ内の隣接するヘックスを取得
    rangeが1より小さい時Exceptionをスロー
    :param col:
    :param row:
    :param range:
    :return: [ [col, row], ... ]
    """

    if _range < 1:
        logging.error("_range : " + str(_range) + " must be over 1")
        raise Exception("レンジの指定は1以上でなければならない。")
        return False

    # レンジ内の隣接するヘックス
    hexes = None
    where = ""
    for i in range(1, _range + 1):
        for j in range(0, _range + 1):
            where += " (col = " + str(col +
                                      j) + " and row = " + str(row - i +
                                                               j) + ") or"
            where += " (col = " + str(col + i -
                                      j) + " and row = " + str(row +
                                                               i) + ") or"
            where += " (col = " + str(col -
                                      i) + " and row = " + str(row -
                                                               j) + ") or"
    where = where[:-3]

    # そのうちDBに実在するもの
    try:
        db = DBSingleton()
        hexex = db.select("col", "row", table="hex_grid", where=where)

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

    return hexex
Exemple #17
0
def update_division_before_move(division_id, food, money, status="moving"):
    """
    移動に伴う部隊情報の更新
    :param division_id: 部隊ID
    :param food: 消費物資
    :param money: 消費資金
    :return: 更新成功 ? True : False
    """
    try:
        db = DBSingleton()
        query = "update division set"  + \
                " food = food - " + str(food) + \
                ", money =money-" + str(money) + \
                " where division_id = \"" + str(division_id) + "\""
        db.exec(query)
        return True

    except DBError as e:
        logging.error(e.message)
        return False
Exemple #18
0
def update_division(division_id, **kwargs):
    """
    部隊の情報更新
    :param division_id:
    :param kwargs:
    :return: 成功 ? True : False
    """
    try:
        db = DBSingleton()

        sentence = "update division set "
        for key, value in kwargs.items():
            sentence = sentence + key + " = \"" + str(value) + "\","
        sentence = sentence[:-1]
        sentence + " where division_id = \"" + str(division_id) + "\""
        db.exec(sentence)
        return True

    except DBError as e:
        return False
    def run(cls):
        u"""ゲームのメインエンジンを起動する
            内部でイベントループを違うスレッドで起動させる"""

        db = DBSingleton()
        status = db.select("status", table="game_status")

        # TODO: 情勢実装
        affair = AffairTest()
        map = MapTest()
        cls._game_settings = {"affair": affair, "map": map}

        print("status: ", status)
        if status[0]["status"] != "ongoing":
            cls.__start_new_year()

        # イベントループスレッド起動
        loop = threading.Thread(target=cls.loop, daemon=False)
        loop.start()

        cls._logger.info("Game system started running")
Exemple #20
0
def update_division_status(division_id, status):
    """
    部隊のステータスを変更
    :param division_id:
    :param status:新しいステータス
    :return: 成功 ? True : False
    """
    if len(status) == 0:
        logging.error(u"statusが空")
        return False

    try:
        db = DBSingleton()
        query = "update division set"  + \
                " status = \"" + str(status) + "\"" \
                " where division_id = \"" + str(division_id) + "\""
        db.exec(query)
        return True

    except DBError as e:
        return False
def get_countryinfo_by_id(country_id):

    try:

        db = DBSingleton()
        result = db.select("country_id",
                           "capital_col",
                           "capital_row",
                           "leader",
                           "country_name",
                           table="country",
                           where="country_id = " + str(country_id))

        if len(result) == 0:
            return None

        return result[0]

    except DBError as e:
        logging.error(e.message)
        return None
def write_bbs_country(_cls, _self, data):
    """会議室へ書き込み"""

    try:

        #DBへ書き込みを追加
        user_id = _self.get_secure_cookie("user_id").decode('utf-8')
        db = DBSingleton()
        country = db.select("country_id", table="user", where="user_id=" + "\""+str(user_id) + "\"")
        country = country[0]
        data = data.replace("\n", "<br>")
        db.insert(table="bbs_country",
                  user_id=str(user_id),
                  country_id=str(country["country_id"]),
                  article=str(data))

    except DBError as e:
        logging.error(u"init_bbs_country.write_bbs_country: 会議室への書き込み失敗。\nmessage = " + e.message)
        raise Exception(u"会議室への書き込み失敗")

    #更新を通知
    update_bbs_country(_cls, _self, {})
def get_playerinfo_by_id(user_id):
    """
    ユーザーIDからプレイヤーの全情報を取得
    :param user_id:
    :return: dict[info_name, ...]
    """

    result = None
    try:
        db = DBSingleton()
        result = db.select(
            "user_name",
            "user_pass",
            "user_id",
            "col",
            "row",
            "country_id",
            "icon_id",
            "division_id",  # 配下の部隊ID
            "status",  # 現在の状態
            table="user",
            where="user_id = \"" + str(user_id) + "\"")

        # TODO : 可視権が国番号のみ
        result[0]["visibility"] = "visibility_" + str(result[0]["country_id"])

    except DBError as e:
        logging.error(e.message)
        raise Exception(u"DBエラー: ユーザー名取得失敗")

    if len(result) == 0:
        logging.error("There's no such a player in DB: user_id = " +
                      str(user_id))
        raise Exception(u"user_idが" + str(user_id) + u"のプレイヤーは存在しない")
        return

    return result[0]
def get_all_countryinfo():
    """
    全ての国の情報を取得
    :return:
    """

    try:

        db = DBSingleton()
        result = db.select("country_id",
                           "capital_col",
                           "capital_row",
                           "leader",
                           "country_name",
                           table="country")

        if len(result) == 0:
            return None

        return result

    except DBError as e:
        logging.error(e.message)
        return None
        user_id = _self.get_secure_cookie("user_id").decode('utf-8')
        db = DBSingleton()
        country = db.select("country_id", table="user", where="user_id=" + "\""+str(user_id) + "\"")
        country = country[0]
        data = data.replace("\n", "<br>")
        db.insert(table="bbs_country",
                  user_id=str(user_id),
                  country_id=str(country["country_id"]),
                  article=str(data))

    except DBError as e:
        logging.error(u"init_bbs_country.write_bbs_country: 会議室への書き込み失敗。\nmessage = " + e.message)
        raise Exception(u"会議室への書き込み失敗")

    #更新を通知
    update_bbs_country(_cls, _self, {})


if __name__ == "__main__":

        db = DBSingleton()
        country = 0
        query = "select user.user_name, user.icon_id, bbs_country.date, bbs_country.article from user " \
                "inner join bbs_country "\
                "on user.user_id=bbs_country.user_id "\
                "where bbs_country.country_id = " + str(country) + \
                " order by bbs_country.date limit 20;"
        result = db.exec(query, True)

        print(result[0][2])
        print(result[0][2].strftime("%Y-%m-%d %H:%M:%S"))
def init_hexgrid(_cls, _self, data):
    """
    クライアントのhex_gridへ初期化情報を送信する
    :param _cls: BJSocketHandlerのクラス
    :param _self: SocketHandlerのインスタンス
    :param data: 空
    :return:
    """

    payload = {"event": "init_hexgrid"}
    data = {}

    #DBから初期化情報を集める
    try:

        db = DBSingleton()

        # ヘックスグリッドの情報
        # TODO: map/map_*.pyからgame_statusのWHLを設定
        """
        result_whl = db.select("width", "height", "length", table="game_status")
        data["width"] = result_whl[0][0]
        data["height"] = result_whl[0][1]
        data["length"] = result_whl[0][2]
        """
        data["width"] = 1500
        data["height"] = 1500
        data["length"] = 50

        # プレイヤー情報(可視権含む)取得
        user_id = _self.get_secure_cookie("user_id").decode('utf-8')
        player = get_playerinfo_by_id(user_id)
        if not player:
            raise Exception("hex_grid上の自身のプレイヤー情報取得失敗")
        print("p0")
        # 可視範囲の全プレイヤー取得
        visible_players = get_players_by_visibility(player["visibility"], True)
        # 自身の情報をペイロードに格納
        data["player_self"] = {
            "name": player["user_name"],
            "col": player["col"],
            "row": player["row"],
            "icon_id": player["icon_id"],
            "country": player["country_id"]
        }
        # 可視範囲の全プレイヤーの情報をペイロードに格納
        payload_players = []
        for visible_player in visible_players:
            payload_players.append({
                "col": visible_player["col"],
                "row": visible_player["row"],
                "icon_id": visible_player["icon_id"],
                "country": visible_player["country_id"]
            })

        data["new_players"] = payload_players

        # 領地の情報
        own_area = get_own_area(player["country_id"])
        data["own_area"] = []
        for hex in own_area:
            data["own_area"].append(hex)

        # 可視範囲のヘックスの情報
        visible_area = get_visible_area(player["visibility"])
        data["visible_area"] = []
        for hex in visible_area:
            data["visible_area"].append(hex)

        # 不可視領域のヘックスの情報
        unvisible_area = get_unvisible_area(player["visibility"])
        data["unvisible_area"] = []
        for hex in unvisible_area:
            data["unvisible_area"].append(hex)

    except Exception as e:
        logging.error(u"ヘックスグリッドの情報取得失敗。\n" u"message = " + str(e))
        _self.send_error(u"ヘックスグリッドの情報取得失敗")
        return

    # 送信するデータ組み立て
    payload["data"] = data

    # 送信
    _self.send_you(payload)