class User extends Base_C_Object {


    constructor(gObject) {

        base.constructor(gObject);
    }

    //获得当前区域
    //@param b boolean
    //@return integer
    function GetArea(b) {
        return Sq_CUser_GetAreaIndex(this.C_Object, b);
    }

    //获得当前区域位置
    //@return integer, integer
    function GetAreaPos() {
        return {
            X = Sq_CUser_GetPosX(this.C_Object),
            Y = Sq_CUser_GetPosY(this.C_Object)
        };
    }

    //获得朝向
    //@return integer, integer
    function GetDirections() {
        return Sq_CUser_Direction(this.C_Object);
    }

    //获得可见values
    //@return integer, integer
    function GetVisibleValues() {
        return Sq_CUser_GetVisibleValues(this.C_Object);
    }

    //获得当前城镇位置
    //@return integer, integer, integer, integer @城镇, 区域, X, Y
    function GetLocation() {
        return {
            Pos = this.GetAreaPos(),
            Town = Sq_CUser_GetTownIndex(this.C_Object),
            Area = Sq_CUser_GetAreaIndex(this.C_Object)
        };
    }

    //账号状态
    //@return integer @after login >= 3
    function GetState() {
        return Sq_CUser_GetState(this.C_Object);
    }

    //角色数量
    //@return integer
    function GetCharacCount() {
        return Sq_CUser_GetCharacCount(this.C_Object);
    }

    //账号ID
    //@return integer
    function GetUID() {
        return Sq_CUser_GetAccId(this.C_Object);
    }

    //唯一ID
    //@return integer
    function GetUniqueId() {
        return Sq_CUser_GetUniqueId(this.C_Object);
    }

    //角色ID
    //@return integer
    function GetCID() {
        return Sq_CUser_GetCharacNo(this.C_Object);
    }

    //角色职业
    //@return integer
    function GetCharacJob() {
        return Sq_CUser_GetCharacJob(this.C_Object);
    }

    //角色名称
    //@return string
    function GetCharacName() {
        return Sq_CUser_GetCharacName(this.C_Object);
    }

    //角色等级
    //@return integer
    function GetCharacLevel() {
        return Sq_CUser_GetCharacLevel(this.C_Object);
    }

    //设置角色等级
    //@param new_level integer
    //@return boolean
    function SetCharacLevel(new_level) {
        Sq_CUser_ChangeGmQuestFlag(this.C_Object, 1);
        Sq_CallFunc(S_Ptr("0x0858EFDE"), "int", ["pointer", "pointer", "int"], S_Ptr("0x0"), this.C_Object, new_level);
        Sq_CUser_ChangeGmQuestFlag(this.C_Object, 0);
    }

    //角色转职职业
    //@return integer
    function GetCharacGrowType() {
        return Sq_CUser_GetCharacGrowType(this.C_Object);
    }

    //角色觉醒职业
    //@return integer
    function GetCharacSecondGrowType() {
        return Sq_CUser_GetCharacSecondGrowType(this.C_Object);
    }

    //更改转职职业 转职职业 是否觉醒
    function ChangeGrowType(GrowType, IsAwa) {
        Sq_CUser_ChangeGrowType(this.C_Object, GrowType, IsAwa);
    }

    //已用疲劳值
    //@return integer
    function GetFatigue() {
        return Sq_CUser_GetFatigue(this.C_Object);
    }

    //最大疲劳值
    //@return integer
    function GetMaxFatigue() {
        return Sq_CUser_GetMaxFatigue(this.C_Object);
    }

    //获取背包
    //@return integer
    function GetInven() {
        local P = Sq_Inven_GetInven(this.C_Object);
        if (P) {
            return Inven(P, this);
        }
        return null;
    }

    //踢人
    //@param src integer @渠道
    //@param p2 integer
    //@param p3 integer
    //@return integer @错误码?
    function Kick(...) {
        local src;
        local p2;
        local p3;
        for (local i = 0; i< vargv.len(); i++) {
            if (i == 0) src = vargv[i];
            if (i == 1) p2 = vargv[i];
            if (i == 2) p3 = vargv[i];
        }

        return Sq_CUser_DisConnSig(this.C_Object, src ? src : 0, p2 ? p2 : 0, p3 ? p3 : 0)
    }

    //踢人
    //@param err @错误号
    //@return integer
    function DisConn(err) {
        return this.Kick(10, 1, err ? err : 1)
    }

    //当前小队/副本
    //@return CParty
    function GetParty() {
        local Ret = Sq_CUser_GetParty(this.C_Object);
        if (Ret) {
            return Party(Ret);
        }
        return null;
    }


    //是否在领主塔
    //@return boolean
    function CheckInBossTower() {
        return (Sq_CUser_CheckInBossTower(this.C_Object) == 1);
    }

    //是否在龙之路
    //@return boolean
    function CheckInBlueMarble() {
        return (Sq_CUser_CheckInBlueMarble(this.C_Object) == 1);
    }

    //是否开启GM权限
    //@return boolean
    function IsGmMode() {
        return (Sq_CUser_IsGmMode(this.C_Object) != 0);
    }

    //获取账号上次退出游戏的时间
    function GetCurCharacLastPlayTick() {
        return Sq_CUser_GetCurCharacLastPlayTick(this.C_Object);
    }

    //获取账号本次登录游戏的时间
    function GetCurCharacLoginTick() {
        return Sq_CallFunc(S_Ptr("0x822F692"), "int", ["pointer"], this.C_Object);
    }

    //获得公网地址
    //@return integer
    function GetIpAddress() {
        return Sq_CallFunc(S_Ptr("0x84EC90A"), "int", ["pointer"], this.C_Object);
    }

    //发包
    function Send(SPacket) {
        Sq_Packet_Send(this.C_Object, SPacket.C_Object);
    }

    //发送自定义包
    function SendJso(Jso) {
        local Str = Json.Encode(Jso);
        if (PacketDebugModel) print("发送包给客户端: " + Str);
        local Pack = Packet();
        Pack.Put_Header(1, 130);
        Pack.Put_Byte(1);
        Pack.Put_Int(Str.len());
        Pack.Put_Binary(Str);
        Pack.Finalize(true);
        Send(Pack);
        Pack.Delete();
    }

    //发送消息包
    function SendNotiPacket(Type1, Type2, Type3) {
        Sq_CUser_SendNotiPacket(this.C_Object, Type1, Type2, Type3);
    }


    //获取技能树
    function GetSkillW() {
        return Sq_CUser_GetSkillW(this.C_Object);
    }

    //重置技能树 转职编号 是否觉醒
    function InitSkillW(GrowType, IsAwa) {
        Sq_CUser_InitSkillW(Sq_CUser_GetSkillW(this.C_Object), GrowType, IsAwa);
    }

    //发送公告消息
    function SendNotiPacketMessage(String, Type) {
        local Pack = Packet();
        Pack.Put_Header(0, 12);
        Pack.Put_Byte(Type);
        Pack.Put_Short(0);
        Pack.Put_Byte(0);
        Pack.Put_Int(String.len());
        Pack.Put_Binary(String);
        Pack.Finalize(true);
        this.Send(Pack);
        Pack.Delete();
    }

    //发送公告消息  字符串数组
    function SendNotiForColorPacketMessage(StringArr, Type) {

        local ColorArr = [];
        local SendStrBlob = blob(1);
        SendStrBlob.writen(0xc2, 'c');
        SendStrBlob.writen(0x80, 'c');
        foreach(sobj in StringArr) {
            local StrPoint = Str_Ptr(sobj[0]);
            local StrPointB = Sq_Point2Blob(StrPoint, sobj[0].len());
            if (sobj[1]) {
                SendStrBlob.writen(0xc2, 'c');
                SendStrBlob.writen(0x80, 'c');
                SendStrBlob.writeblob(StrPointB);
                SendStrBlob.writen(0xc2, 'c');
                SendStrBlob.writen(0x80, 'c');

                local ColorBlob = blob(104);
                for (local i = 0; i< 3; i++) {
                    ColorBlob.writen(sobj[2][i], 'c');
                }
                for (local i = 0; i< 101; i++) {
                    ColorBlob.writen(0xff, 'c');
                }
                local ColorPoint = Sq_New_Point(104);
                Sq_WriteBlobToAddress(ColorPoint, ColorBlob);
                ColorArr.append(ColorPoint);

            } else {
                SendStrBlob.writeblob(StrPointB);
            }
        }

        local SendStrLen = SendStrBlob.len();
        local SendStrPoint = Sq_New_Point(SendStrLen);
        Sq_WriteBlobToAddress(SendStrPoint, SendStrBlob);

        local Pack = Packet();
        Pack.Put_Header(0, 370);
        Pack.Put_Byte(Type);
        Pack.Put_Short(0);
        Pack.Put_Byte(3);
        Pack.Put_Int(SendStrLen);
        Pack.Put_BinaryEx(SendStrPoint, SendStrLen);
        Pack.Put_Byte(ColorArr.len());
        foreach(color in ColorArr) {
            Pack.Put_BinaryEx(color, 3);
        }
        Pack.Finalize(true);
        Send(Pack);
        Pack.Delete();
        SendItemSpace(0);

        Sq_Delete_Point(SendStrPoint);
        for (local i = 0; i< ColorArr.len(); i++) {
            Sq_Delete_Point(ColorArr[i]);
        }
    }

    //发送公告消息  字符串数组 带ID
    function SendNotiForColorAIdPacketMessage(StringArr, Type) {
        local ColorArr = [];
        local SendStrBlob = blob(1);
        SendStrBlob.writen(0xc2, 'c');
        SendStrBlob.writen(0x80, 'c');
        foreach(sobj in StringArr) {
            local StrPoint = Str_Ptr(sobj[0]);
            local StrPointB = Sq_Point2Blob(StrPoint, sobj[0].len());
            if (sobj[1]) {
                SendStrBlob.writen(0xc2, 'c');
                SendStrBlob.writen(0x80, 'c');
                SendStrBlob.writeblob(StrPointB);
                SendStrBlob.writen(0xc2, 'c');
                SendStrBlob.writen(0x80, 'c');

                local ColorBlob = blob(104);
                for (local i = 0; i< 3; i++) {
                    ColorBlob.writen(sobj[2][i], 'c');
                }
                if (sobj[3]) {
                    ColorBlob.seek(4);
                    ColorBlob.writen(sobj[3], 'i');
                } else {
                    for (local i = 0; i< 101; i++) {
                        ColorBlob.writen(0xff, 'c');
                    }
                }
                local ColorPoint = Sq_New_Point(104);
                Sq_WriteBlobToAddress(ColorPoint, ColorBlob);
                ColorArr.append(ColorPoint);

            } else {
                SendStrBlob.writeblob(StrPointB);
            }
        }

        local SendStrLen = SendStrBlob.len();
        local SendStrPoint = Sq_New_Point(SendStrLen);
        Sq_WriteBlobToAddress(SendStrPoint, SendStrBlob);

        local Pack = Packet();
        Pack.Put_Header(0, 370);
        Pack.Put_Byte(Type);
        Pack.Put_Short(0);
        Pack.Put_Byte(3);
        Pack.Put_Int(SendStrLen);
        Pack.Put_BinaryEx(SendStrPoint, SendStrLen);
        Pack.Put_Byte(ColorArr.len());
        foreach(color in ColorArr) {
            Pack.Put_BinaryEx(color, 104);
        }
        Pack.Finalize(true);
        Send(Pack);
        Pack.Delete();
        SendItemSpace(0);
        Sq_Delete_Point(SendStrPoint);
        for (local i = 0; i< ColorArr.len(); i++) {
            Sq_Delete_Point(ColorArr[i]);
        }
    }


    //调试信息包
    function Debug(Any) {
        local Time = date();
        local TStr = format("[%d年%d月%d日%d时%d分%d秒]\n", Time.year, Time.month, Time.day, Time.hour, Time.min, Time.sec);
        SendNotiPacketMessage(TStr + Any.tostring(), 8);
    }

    //发送道具
    function GiveItem(ItemId, ItemCount) {
        //如果开了调试
        if ("DebugModelFlag" in getroottable()) {
            local Flag = PvfItem.GetPvfItemById(ItemId);
            if (!Flag) {
                print("未找到Pvf道具: " + ItemId);
                return null;
            }
        }
        local Info = Sq_CUser_GiveUserItem(this.C_Object, ItemId, ItemCount);
        if (Info) { //发送成功就刷新背包
            Sq_CUser_SendUpdateItemList(this.C_Object, 1, Info[0], Info[1]);
            return Info;
        } else return null;
    }
    //发送道具 如果背包满则发送邮件
    function GiveItemEx(GiveTab) {
        local mitems = {};
        foreach(i, v in GiveTab) {
            local Ret = GiveItem(v.id, v.count);
            if (!Ret) mitems[v.id] <- v.count;
        }
        if (mitems.len() > 0) {
            SendMail(mitems, {
                Title = "系统",
                Text = "由于你的包裹已满, 请留出足够的空间来接收道具."
            })
        }
    }

    //更新背包栏
    function SendItemSpace(ItemSpace) {
        Sq_CallFunc(S_Ptr("0x865DB6C"), "int", ["pointer", "int"], this.C_Object, ItemSpace);
    }

    //更新道具信息
    function SendUpdateItemList(Type, ItemSpace, Slot) {
        Sq_CUser_SendUpdateItemList(this.C_Object, Type, ItemSpace, Slot);
    }

    //发送系统邮件
    function SendMail(ItemList, ...) {
        local SGold = 0;
        local STitle = "GM邮件";
        local SText = "这是Gm给您发送的邮件";
        if (vargv.len() > 0) {
            local T = vargv[0];
            if ("Gold" in T) SGold = T.Gold;
            if ("Title" in T) STitle = T.Title;
            if ("Text" in T) SText = T.Text;
        }
        Sq_CUser_SendMail(GetCID(), ItemList, SGold, STitle, SText);
    }

    //无条件完成指定任务并领取奖励
    function ClearQuest_Gm(QuestId) {
        Sq_CUser_ChangeGmQuestFlag(this.C_Object, 1);
        Sq_CUser_QuestAction(this.C_Object, 33, QuestId, 0, 0);
        Sq_CUser_QuestAction(this.C_Object, 35, QuestId, 0, 0);
        Sq_CUser_QuestAction(this.C_Object, 36, QuestId, -1, 1);
        Sq_CUser_RefreshLastQuestTime(this.C_Object);
        Sq_CUser_ChangeGmQuestFlag(this.C_Object, 0);
    }

    //充值点券
    function RechargeCera(Amount) {
        Sq_CUser_RechargeCoupons(this.C_Object, Amount);
    }
    //获取点券
    function GetCera() {
        return Sq_CallFunc(S_Ptr("0x080FDF7A"), "int", ["pointer"], this.C_Object);
    }
    //充值代币券
    function RechargeCeraPoint(Amount) {
        Sq_CUser_RechargeCouponsPoint(this.C_Object, Amount);
    }
    //获取代币券
    function GetCeraPoint() {
        return Sq_CallFunc(S_Ptr("0x08692af6"), "int", ["pointer"], this.C_Object);
    }
    //充值金币
    function RechargeMoney(Amount) {
        Sq_CallFunc(S_Ptr("0x84FF29C"), "int", ["pointer", "int", "int", "int", "int"], Sq_CallFunc(S_Ptr("0x80DA28E"), "pointer", ["pointer"], this.C_Object), Amount, 0, 0, 0);
    }
    //充值胜点
    function RechargeWinPoint(Amount) {
        return Sq_CallFunc(S_Ptr("0x0864fd2c"), "int", ["pointer", "int", "int"], this.C_Object, Amount, 6);
    }
    //获取胜点
    function GetWinPoint() {
        return Sq_CallFunc(S_Ptr("0x0817a17c"), "int", ["pointer"], this.C_Object);
    }
    //获取复活币
    function GetCoin() {
        local Count = Sq_CallFunc(S_Ptr("0x086966b4"), "int", ["pointer"], this.C_Object) + Sq_CallFunc(S_Ptr("0x086966e0"), "int", ["pointer"], this.C_Object) + Sq_CallFunc(S_Ptr("0x0869670c"), "int", ["pointer"], this.C_Object);
        return Count;
    }

    //离开队伍
    function LeaveParty() {
        local PartyObj = GetParty();
        if (PartyObj) {
            PartyObj.LeaveUser(this);
        }
    }

    //放弃副本
    function GiveupDgn() {
        local PartyObj = GetParty();
        if (PartyObj) {
            PartyObj.LeaveUserOnDgn(this);
        }
    }

    //设置玩家坐标
    function SetPosition(Xpos, Ypos, Direction) {
        Sq_CallFunc(S_Ptr("0x082F0E2A"), "pointer", ["pointer", "int", "int", "short"], this.C_Object, Xpos, Ypos, Direction);
    }

    //获取玩家任务信息
    function GetQuest() {
        return Sq_CallFunc(S_Ptr("0x814AA5E"), "pointer", ["pointer"], this.C_Object);
    }

    //获取玩家账号金库
    function GetAccountCargo() {
        local Ret = Sq_CallFunc(S_Ptr("0x0822fc22"), "pointer", ["pointer"], this.C_Object);
        if (Ret) return AccountCargo(Ret, this);
        else return null;
    }
}