SKYXY客服
x
第五章 arcalet教程(2) - DP讀寫操作 | skyxy
快速建站
︿
TOP
首頁 > 入門學習 > 文章內容
第五章 arcalet教程(2) - DP讀寫操作
12/25/2016 3:14:43 PM
瀏覽數:454
沈夜
DP讀寫操作
了解dp的使用方法後,我們再繼續學習如何使用 super user 去修改後台item的數值。

此範例運用三種超級使用者指令來完成以下的工作:
新增玩家的ItemInstance 取得玩家的ItemInstance 修改玩家ItemInstance的屬性
(超級使用者跟一般使用者的api 大同小異,只差在需要輸入多一個需要修改玩家的Userid)
DP端:
程式碼部分與上一個登入的一樣 但我們要再加入幾行程式碼

1. 在  #region Variables 裡面增加Iguid欄位
private const string sguid_game = ""; 

2. 由於我們要用到 private message 所以要在 DP_001_Load 函式裡面增加
ag.onPrivateMessageIn += PrivateMessageIn;
其他需要增加的函式 (下列程式碼):
Code:
C#
void PrivateMessageIn(string msg, int delay, ArcaletGame game)
        {
            Console.WriteLine("PrivateMsgIn: " + msg);
            //使用Try Catch處理訊息可以避免收到錯誤訊息造成DP Exception
            try
            {
                string[] cmds = msg.Split(':'); //將收到的訊息以分號":" 區隔
                switch (cmds[0])
                {
                    case "item_new": DP_NewItemInstance(cmds[1].Split('/')); break;
                    case "attr_set": DP_SetItemAttribute(cmds[1].Split('/')); break;
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }

        void DP_NewItemInstance(string[] msg)
        {
            //將玩家訊息轉換成userid
            string user = msg[0];
            int poid = int.Parse(msg[1]);

            //新增玩家的ItemInstance
            ArcaletItem.suNewItemInstance(ag, user, iguid, CB_NewPlayerItemInstance, msg);
        }

        void CB_NewPlayerItemInstance(int code, object data, object token)
        {
            string[] info = token as string[];
            int poid = int.Parse(info[1]);
            int itemID = (int)data;

            if (code == 0)
            {
                label3.Text = "New ItemInstance Successed,Item ID: " + itemID;
                ag.PrivacySend("dp_succ:New/" + itemID, poid);
            }
            else
            {
                label3.Text = "New ItemInstance Failed,Error Code: " + code;
                ag.PrivacySend("dp_err:New/" + code, poid);
            }
        }

        void DP_SetItemAttribute(string[] msg)
        {
            Console.WriteLine("SetItemAttribute Msg:" + msg);

            string user = msg[0]; //取出user
            int poid = int.Parse(msg[1]);
            string iguid = msg[2];
            string attr_name = msg[3];
            int itemID = int.Parse(msg[4]);
            string attr_value = msg[5];
            ArcaletItem.suSetItemInstanceAttribute(ag, user, iguid, itemID, attr_name, attr_value, CB_SetPlayerAttribute, poid);
        }

    
        void CB_SetPlayerAttribute(int code, object token)
        {
            if (code == 0)
            {
                int poid = (int)token;

                label3.Text = "Set Item Atrribute Successed";
                ag.PrivacySend("dp_succ:set", poid);
            }
            else
            {
                label3.Text = "Set Item Atrribute Failed\r\nError Code: " + code;
            }
        }
訊息處理:
從我們的程式碼可以看出來,我們訊息都是以符號 "/" 或 ":" 寄出去的,這個用意是為了可以讓我們的訊息只發送一行就能附帶各種訊息出去。(使用 split指令 )
當然開發者可以選擇如json等插件來執行這個功能,因為這2個符號會導致日期等格式發生問題。

安全性問題:
當然,由於是範例的關係,我們直接使用了client端呼叫Dp的方式去修改數值。
在正常的服務器邏輯下,這樣做是非常危險的,因為玩家還是能通過修改發出的訊息修改物品。如果要做到這樣的功能,所有數值的計算都要在Dp上執行才能達到安全的效果。
(如:玩家升等不是由client端叫dp修改,而是client端請dp檢查是否升等才傳回正確數值)
Client 端:
client端部分除了GetItemInstance 是從後台直接抓取外,其他都是通過dp更新的。
這麼做的原因是一來 item因為訊息沒辦法夾帶大量的訊息傳送(有最大字數限定),二來是因為讀取是不會影響數值的(不會有安全性問題)。
由於client 端部分已之前的範例大同小異 所以Code部分請自行下載測試。
PS:雖然界面上與之前範例無異,但卻是通過dp更新數據的。(除了GetItemInstance)
執行畫面:
您也可能喜歡這些文章
留言給作者
不公開此留言     登入即可留言
讀者留言
載入更多留言