/*
文件名:Exchange.nut
路径:Dps_A/ProjectClass/Exchange/Exchange.nut
创建日期:2025-07-21	19:05
文件用途:
*/

class Exchange {

    MysqlObject = null;
    Commission = 0;

    constructor() {

        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"));

        SelectSql("CREATE TABLE `zyk`.`exchange`  (  `uuid` int NOT NULL AUTO_INCREMENT,  `type` int NULL,  `itemid` int NULL,  `itemcount` int NULL,  `itemdata` varchar(512) NULL,  `price` int NULL,  `uid` int NULL , `cid` int NULL , `name` varchar(128) NULL,  PRIMARY KEY (`uuid`));", []);



        local Ct = ScriptData.GetFileData("etc/rindro/exchange/exchange.etc", function(DataTable, Data) {
            DataTable.Attribute <- {};
            while (!Data.Eof()) {
                local Str = Data.Get();
                if (Str == "[commission]") {
                    Commission = Data.Get().tofloat() * 0.01;
                }
            }
        }.bindenv(this));

        //上架商品
        ClientSocketPackFuncMap.rawset(21001001, function(SUser, Jso) {
            //获取玩家背包
            local InvenObj = SUser.GetInven();
            if (!InvenObj) {
                return;
            }

            //获取道具
            local ItemObj = InvenObj.GetSlot(1, Jso.pos + 9 + (Jso.type * 48));
            if (!ItemObj) return;

            //获取道具类型
            ItemObj.Attribute.seek(1);
            local ItemType = ItemObj.Attribute.readn('c');
            //副职业材料是10 这里给转成5
            if (ItemType == 10) ItemType = 5;

            //获取道具Id
            local ItemId = ItemObj.GetIndex();
            //获取数量
            local ItemCount = ItemObj.GetAdd_Info();
            //如果是装备 数量恒定为1
            if (ItemType == 1) ItemCount = 1;

            //获取道具数据
            local ItemData = "0x00";

            //获取价格
            local Price = Jso.value;
            //获取上架者cid
            local Uid = SUser.GetUID();
            local Cid = SUser.GetCID();
            local Name = SUser.GetCharacName();

            local InfoTable = {
                ItemType = ItemType,
                ItemId = ItemId,
                ItemCount = ItemCount,
                ItemData = ItemData,
                Price = Price,
                Uid = Uid,
                Cid = Cid,
                Name = Name
            }

            if (ItemType == 1) {
                EquipLogic(SUser, Jso.pos + 9, InfoTable, ItemObj);
                return;
            }

            //插入数据库
            local Sql = format("INSERT INTO `zyk`.`exchange` (`type`, `itemid`, `itemcount`, `itemdata`, `price`, `uid` ,`cid`,`name`) VALUES (%d, %d, %d, \'%s\', %d, %d, %d, \'%s\');", InfoTable.ItemType, InfoTable.ItemId, InfoTable.ItemCount, InfoTable.ItemData, InfoTable.Price, InfoTable.Uid, InfoTable.Cid, InfoTable.Name);
            local Ret = SelectSql(Sql, []);

            //删除道具
            ItemObj.Delete();
            //发送刷新背包消息
            SUser.SendUpdateItemList(1, 1, Jso.pos + 9 + (Jso.type * 48));
            SUser.SendItemSpace(0);
        }.bindenv(this));


        //查询上架商品
        ClientSocketPackFuncMap.rawset(21001003, function(SUser, Jso) {
            local Offset = Jso.offset;
            local Sql = format("SELECT * FROM `zyk`.`exchange` WHERE `type` = %d LIMIT 7 OFFSET %d;", Jso.type, Offset);
            local Ret = SelectSql(Sql, ["int", "int", "int", "int", "binary", "int", "int", "int", "string"]);

            local CountSql = format("SELECT COUNT(*) AS total FROM `zyk`.`exchange` WHERE `type` = %d;", Jso.type);
            local CountRet = SelectSql(CountSql, ["int"]);

            local TotalCount = 0;
            if (CountRet.len() > 0) TotalCount = CountRet[0][0];

            local Pack = {};
            Pack.op <- 21001004;
            Pack.info <- [];
            Pack.total <- TotalCount;
            foreach(info in Ret) {
                local T = {
                    uid = info[0],
                    itemId = info[2],
                    count = info[3],
                    price = info[5],
                    name = info[8]
                }
                Pack.info.push(T);
            }
            SUser.SendJso(Pack);

        }.bindenv(this));

        //购买商品
        ClientSocketPackFuncMap.rawset(21001005, function(SUser, Jso) {
            local uuid = Jso.uuid;

            local Sql = format("SELECT * FROM `zyk`.`exchange` WHERE `uuid` = %d;", uuid);
            local Ret = SelectSql(Sql, ["int", "int", "int", "int", "string", "int", "int", "int", "string"]);
            if (Ret.len() == 0) return;

            local ItemObj = null;
            local ItemType = Ret[0][1];
            local ItemId = Ret[0][2];
            local ItemCount = Ret[0][3];
            local ItemPrice = Ret[0][5];
            local ItemData = Ret[0][4];
            local uid = Ret[0][6];
            local cid = Ret[0][7];

            local SelfCid = SUser.GetCID();
            if (SelfCid == cid) return;

            local UserPoint = SUser.GetCera();
            if (UserPoint< ItemPrice) return;

            //扣除点券
            SUser.RechargeCera(-ItemPrice);

            //如果是装备
            if (ItemType == 1) {
                local ItemDataJso = Json.Decode(ItemData);
                SendItemExMail(SUser.GetUID(), SUser.GetCID(), [ItemDataJso], "交易所小助手", "您在交易所购买的商品已发货,请查收!");
            } else {
                //发送道具
                local SendInfo = SUser.GiveItem(ItemId, 1);
                SUser.SendItemSpace(0);
            }

            //给上架者加钱
            local RealItemPrice = (ItemPrice * (1.0 - Commission.tofloat()).tofloat()).tointeger();
            User.SendItemMail(uid, cid, [{
                // item = 2022110573,
                item = 3037,
                num = RealItemPrice
            }], "交易所小助手", "恭喜您在交易所成功出售商品，获得点券奖励");

            //删除数据库中的记录
            Sql = format("DELETE FROM `zyk`.`exchange` WHERE `uuid` = %d;", uuid);
            SelectSql(Sql, []);

        }.bindenv(this));


        Cb_Use_Item_Sp_Func[2022110573] <- function(SUser, ItemId) {
            local Cid = SUser.GetCID();
            local InvenObj = SUser.GetInven();
            if (InvenObj) {
                local SlotIdx = InvenObj.GetSlotById(ItemId);
                local ItemObj = InvenObj.GetSlot(1, SlotIdx);

                local ItemCount = ItemObj.GetAdd_Info();
                ItemObj.Delete();
                SUser.SendItemSpace(0);
                SUser.RechargeCera(ItemCount);
                SUser.SendNotiPacketMessage("获得交易所点卷收益: " + ItemCount + "点卷", 8);
            }
        }
    }

    function EquipLogic(SUser, slot, InfoTable, ItemObj) {
        Sq_CallFunc(S_Ptr("0x0864FE52"), "int", ["pointer"], SUser.C_Object);
        Timer.SetTimeOut(function() {
            local SqlObj = MysqlPool.GetInstance().GetConnect();
            local Ret = SqlObj.Select("SELECT inventory FROM taiwan_cain_2nd.inventory WHERE charac_no = " + SUser.GetCID() + ";", ["binary"]);
            //把连接还池子
            MysqlPool.GetInstance().PutConnect(SqlObj);
            if (Ret.len()< 1 || Ret[0][0] == null) {
                return false;
            } else {
                local LengthPointer = Memory.alloc(4);
                LengthPointer.writeInt(18238);

                local ReadPointer = Memory.alloc(18238);

                local Flag = Sq_CallFunc(S_Ptr("0x086B2102"), "bool", ["pointer", "pointer", "pointer", "int"], ReadPointer.C_Object, LengthPointer.C_Object, Ret[0][0].C_Object, Ret[0][0].Size);

                local RealP = ReadPointer.add(2 + slot * 61);

                //装备编号
                local ItemId = RealP.readInt();
                // print("装备编号: " + ItemId);

                //强化等级
                local EnhancementLevel = RealP.add(4).readS8();
                // print("强化等级: " + EnhancementLevel);

                //红字类型
                local AmplifyType = RealP.add(15).readS8();
                // print("红字类型: " + AmplifyType);

                //红字属性值
                local AmplifyValue = RealP.add(16).readS8();
                // print("红字属性值: " + AmplifyValue);

                //锻造等级
                local ForgingGrade = RealP.add(49).readS8();
                // print("锻造等级: " + ForgingGrade);

                //附魔卡片
                local CardId = RealP.add(11).readShort();
                // print("附魔卡片: " + CardId);

                //品级
                local Grade = RealP.add(5).readInt();
                // print("品级: " + Grade);

                //耐久度
                local Durability = RealP.add(9).readS8();
                // print("耐久度: " + Durability)

                //魔法封印
                local MagicSealP = "0x";
                for (local i = 0; i< 14; i++) {
                    MagicSealP += format("%02x", RealP.add(35 + i).readU8());
                }
                // print(MagicSealP);

                local SendT = {
                    ItemId = ItemId,
                    Grade = Grade,
                    Durability = Durability,
                    EnhancementLevel = EnhancementLevel,
                    AmplifyType = AmplifyType,
                    AmplifyValue = AmplifyValue,
                    MagicSealP = MagicSealP,
                    CardId = CardId,
                }

                local Json = Json.Encode(SendT);
                InfoTable.ItemData = Json;

                //插入数据库
                local Sql = format("INSERT INTO `zyk`.`exchange` (`type`, `itemid`, `itemcount`, `itemdata`, `price`, `uid` ,`cid`,`name`) VALUES (%d, %d, %d, \'%s\', %d, %d, %d, \'%s\');", InfoTable.ItemType, InfoTable.ItemId, InfoTable.ItemCount, InfoTable.ItemData, InfoTable.Price, InfoTable.Uid, InfoTable.Cid, InfoTable.Name);
                local Ret = SelectSql(Sql, []);

                //删除道具
                ItemObj.Delete();
                //发送刷新背包消息
                SUser.SendUpdateItemList(1, 1, slot);
                SUser.SendItemSpace(0);
            }
        }.bindenv(this), 1)
    }


    function SendItemExMail(UID, CID, ItemList, title, content) {
        local SUser = World.GetUserByUid(UID);
        local sql = "select letter_id from taiwan_cain_2nd.postal order by letter_id DESC";
        local column_type_list = ["int"];

        local SqlObj = MysqlPool.GetInstance().GetConnect();
        local result = SqlObj.Select(sql, column_type_list);
        local sl = 1;
        if (result.len() > 0) {
            sl = result[0][0] + 1;
        }

        local time = date();
        local timeStr = time["year"] + "-" + (time["month"] + 1) + "-" + time["day"] + " " + time["hour"] + ":" + time["min"] + ":" + time["sec"];

        foreach(value in ItemList) {
            //时间  发送者名字   接收者id  装备ID 品级 耐久度 强化等级 红字类型 红字属性值 魔法封印属性 letterid
            local sql1 = format("insert into taiwan_cain_2nd.postal (occ_time,send_charac_name,receive_charac_no,item_id,add_info,endurance,upgrade,amplify_option,amplify_value,random_option,letter_id,extend_info) values ('%s','%s',%d,%d,%d,%d,%d,%d,%d,%s,%d,%d)", timeStr, title, CID, value.ItemId, value.Grade, value.Durability, value.EnhancementLevel, value.AmplifyType, value.AmplifyValue, value.MagicSealP, sl, value.CardId)
            SqlObj.Select(sql1, []);
        }

        local sql2 = "insert into taiwan_cain_2nd.letter (letter_id,charac_no,send_charac_name,letter_text,reg_date,stat) values ('" + sl + "'," + CID + ",'" + title + "','" + content + "','" + timeStr + "','1')";
        SqlObj.Select(sql2, []);

        MysqlPool.GetInstance().PutConnect(SqlObj);

        // if (SUser) {
        //     local Pack = Packet();
        //     Pack.Put_Header(0, 9);
        //     local MailBox = Sq_CallFunc(S_Ptr("0x0823020C"), "int", ["pointer"], SUser.C_Object);
        //     Sq_CallFunc(S_Ptr("0x0823455A"), "int", ["int"], MailBox);
        //     local Not_Count = Sq_CallFunc(S_Ptr("0x084ED330"), "int", ["int"], MailBox);
        //     Pack.Put_Short(Not_Count);
        //     Pack.Finalize(true);
        //     SUser.Send(Pack);
        //     Pack.Delete();
        // }
    }



    //执行数据库命令
    function SelectSql(Sql, Type) {
        local Ret = MysqlObject.Select(Sql, Type);
        return Ret;
    }

}


ProjectInitFuncMap.P_Exchange <- Exchange();