class _DPS_Login_Gateway_ {

    //数据库连接
    MysqlObject = null;

    PackHandleMap = null;

    constructor() {
        PackHandleMap = {};

        MysqlObject = Mysql(Str_Ptr("127.0.0.1"), 3306, Str_Ptr("taiwan_cain"), Str_Ptr("game"), Str_Ptr("uu5!^%jg"));
        MysqlObject.Exec_Sql(format("SET NAMES %s", "latin1"));

        //创建一个Http Server
        try {
            local HS = HttpServer("0.0.0.0", "41817");
            HS.Listen(function(SocketObject, Header, Msg) {
                print("HS.Listen")
                getroottable()._DPS_Login_Gateway_Object_._HttpServer_Event_DPS_(SocketObject, Header, Msg);
            });
        } catch (exception) {

        }

        PackHandleMap["/GetConfig"] <- function(SocketObject, Header, Jso) {
            local Config = sq_ReadJsonFile("/dp_s/OfficialConfig/登录器配置.json");
            //读取DPS登录器的配置并发送
            SocketObject.Write(Config);
        }


        PackHandleMap["/Login"] <- function(SocketObject, Header, Jso) {
            if (!Jso.rawin("account")) return;
            if (!Jso.rawin("passwd")) return;
            local account = Jso.account;
            local passwd = Jso.passwd;
            local passwd_hash = MD5_Hash(passwd);


            //正则表达式 只允许字母和数字
            local regex = regexp("^[A-Za-z0-9]{1,19}$");
            if (!regex.match(account)) {
                SocketObject.Write({
                    error = "账号只能包含字母和数字且长度小于20"
                });
                return;
            }

            local sql = format("select UID from d_taiwan.accounts where accountname='%s' and password='%s';", account, passwd_hash);
            local Ret = MysqlObject.Select(sql, ["int"]);
            if (Ret && Ret.len() > 0) {
                local Uid = Ret[0][0];
                local str = format("%08x010101010101010101010101010101010101010101010101010101010101010155914510010403030101", Uid);
                local Byte = Sq_Rsa_Private_Encrypt(str);
                local EnStr = MD5.base64_encode(Byte);
                //发送登录Token
                SocketObject.Write({
                    token = EnStr
                });
            } else {
                SocketObject.Write({
                    error = "账号或密码错误!"
                });
            }
        }.bindenv(this);


        PackHandleMap["/Register"] <- function(SocketObject, Header, Jso) {

            if (!Jso.rawin("account")) return;
            if (!Jso.rawin("passwd")) return;

            local account = Jso.account;
            local passwd = Jso.passwd;


            //正则表达式 只允许字母和数字
            local regex = regexp("^[A-Za-z0-9]{1,19}$");
            if (account.len() == 0 || !regex.match(account)) {
                SocketObject.Write({
                    error = "账号只能包含字母和数字且长度大于0小于20"
                });
                return;
            }
            if (passwd.len() == 0 || !regex.match(passwd)) {
                SocketObject.Write({
                    error = "密码只能包含字母和数字且长度大于0小于20"
                });
                return;
            }
            if (GetAccountByName(account) != null) {
                SocketObject.Write({
                    error = "账号已存在"
                })
                return;
            }
            local passwd_hash = MD5_Hash(passwd);


            local sql = format("INSERT INTO d_taiwan.accounts(accountname, password)VALUES( '%s' , '%s');", account, passwd_hash);
            MysqlObject.Exec_Sql(sql);
            local Ret = MysqlObject.Select("SELECT LAST_INSERT_ID()", ["int"]);
            if (Ret && Ret.len() > 0) {
                local Uid = Ret[0][0].tostring();
                MysqlObject.Exec_Sql(format("INSERT INTO d_taiwan.member_info(m_id, user_id)VALUES('%s','%s');", Uid, Uid));
                MysqlObject.Exec_Sql(format("INSERT INTO d_taiwan.member_white_account(m_id)VALUES('%s')", Uid));
                MysqlObject.Exec_Sql(format("INSERT INTO taiwan_login.member_login(m_id)VALUES('%s')", Uid));
                MysqlObject.Exec_Sql(format("INSERT INTO taiwan_billing.cash_cera(account, cera,mod_tran,mod_date, reg_date)VALUES('%s',0,0,NOW(), NOW())", Uid));
                MysqlObject.Exec_Sql(format("INSERT INTO taiwan_billing.cash_cera_point(account, cera_point,mod_date, reg_date)VALUES('%s',0,NOW(), NOW())", Uid));
                SocketObject.Write({
                    success = "账号注册成功,现在您可以登录了!"
                });
                return;
            }

        }.bindenv(this);


    }


    function GetAccountByName(account) {
        local sql = format("select UID , accountname, password from d_taiwan.accounts where accountname='%s'", account);
        local Ret = MysqlObject.Select(sql, ["int", "string", "string"]);
        print(Ret);
        if (!Ret || Ret.len() == 0) {
            return null;
        }

        return {
            uid = Ret[0][0],
            account = Ret[0][1],
            passwd = Ret[0][2]
        }
    }

    function _HttpServer_Event_DPS_(SocketObject, Header, Msg) {
        print("_HttpServer_Event_DPS_")
        if (PackHandleMap.rawin(Header.path)) {
            local Jso = null;
            try {
                Jso = Json.Decode(Msg);
            } catch (exception) {

            }
            if (!Jso) return;
            print(Jso);
            PackHandleMap[Header.path](SocketObject, Header, Jso);

        } else {
            SocketObject.Write({
                error = "error url"
            });
        }
    }

    function MD5_Hash(str) {
        local Ctx = Memory.alloc(0x100);
        MD5.MD5_Init(Ctx.C_Object);
        MD5.MD5_Update(Ctx.C_Object, Memory.allocUtf8String(str).C_Object, str.len());
        local Result = Memory.alloc(16);
        MD5.MD5_Final(Result.C_Object, Ctx.C_Object);
        return MD5.hex_encode(Result.readUtf8String(16));
    }
}


Timer.SetTimeOut(function() {
    getroottable()._DPS_Login_Gateway_Object_ <- _DPS_Login_Gateway_();
}, 1);