--- title: '寶可夢Server架構' ---[TOC] # 測試方式 ### 通訊協定 = websocket ### port = 10001 ### IP = 35.230.88.33 ### 連線url = ws://35.230.88.33:10001/GameCmd ### data 格式 json字串 ### 加密方式 目前debug版無加密 正式release版使用AES加解密 ### 不用寫code 連線小工具 http://www.websocket.org/echo.html ![](https://i.imgur.com/UcodThw.png) Location 欄位貼上 ws://35.230.88.33:10001/GameCmd 按下 connect 按鈕即可連線到 gameServer 下面Message 欄位就是要貼上的 封包 json 字串 接著按下 send 按鈕即可送出封包 右邊Log框是server回應訊息 # 封包: ## 註冊帳號封包 Cmd=createAccount 請求封包格式 | 欄位 | 資料型態 | 內容 | | -------- | -------- | -------- | | sys | string | 系統(system)或遊戲(game) | | cmd | string | 封包名稱 | | isEncode | bool | 加密與否 | | data | Obj | Text | | platformId | Text | 平台編號 | | account | string | 帳號 | | password | string | 密碼 | | nickName | string | 玩家暱稱 | | phoneNumber | string | 玩家電話號碼 | | email | string | 玩家電子郵箱 | | privateKey | string | 區塊鍊密鑰 | | token | string | 區塊鍊Token | | referrerUserId | int | 推薦人會員Id | ```json= { "sys":"system", "cmd":"createAccount", "isEncode":false, "data":{ "platformId":1, "account":"cat111", "password":"1234", "nickName":"新人王", "phoneNumber":"09xx123456", "email":"dog111@gmail.com", "privateKey": "區塊鍊密鑰", "token": "0x9dAA47E1d50A0b19bd2001d0d4468cf533551bd9" "referrerUserId":112233 } } ``` 回應封包格式 | 欄位 | 資料型態 | 內容 | | -------- | -------- | -------- | | sys | string | 系統(system)或遊戲(game) | | cmd | string | 封包名稱 | | isEncode | bool | 加密與否 | | data | Obj | Text | | platformId | Text | 平台編號 | | account | string | 帳號 | | password | string | 密碼 | | nickName | string | 暱稱 | | balance | float | 會員點數 | | email | string | 玩家電子郵箱 | | privateKey | string | 區塊鍊密鑰 | | token | string | 區塊鍊Token | | referrerUserId | int | 推薦人會員Id | ```json= { "code":0, "message":"回應成功阿", "sys":"system", "clientId":0, "sn":0, "isEncode":false, "ver":0, "ret":"login", "data":{ "userId":1, "account":"cat111", "nickName":"新人王", "balance":0, "token":"a9cdd49e-6afc-4456-a9f0-3aa7ab7c31a6", "email":"dog111@gmail.com", "privateKey": "區塊鍊密鑰", "token": "0x9dAA47E1d50A0b19bd2001d0d4468cf533551bd9", "referrerUserId":112233 } } ``` # 封包: ## 登入封包 Cmd=login 請求封包格式 | 欄位 | 資料型態 | 內容 | | -------- | -------- | -------- | | sys | string | 系統(system)或遊戲(game) | | cmd | string | 封包名稱 | | isEncode | bool | 加密與否 | | data | Obj | Text | | platformId | Text | 平台編號 | | account | string | 帳號 | | password | string | 密碼 | ```json= { "sys":"system", "cmd":"login", "isEncode":false, "data":{ "platformId":1, "account":"cat111", "password":"1234" } } ``` 回應封包格式 | 欄位 | 資料型態 | 內容 | | -------- | -------- | -------- | | sys | string | 系統(system)或遊戲(game) | | cmd | string | 封包名稱 | | isEncode | bool | 加密與否 | | data | Obj | Text | | platformId | Text | 平台編號 | | account | string | 帳號 | | password | string | 密碼 | | nickName | string | 暱稱 | | balance | float | 會員點數 | | token | string | token | ```json= { "code":0, "message":"回應成功阿", "sys":"system", "clientId":0, "sn":0, "isEncode":false, "ver":0, "ret":"login", "data":{ "userId":1, "account":"cat111", "nickName":"無名1", "balance":0, "token":"a9cdd49e-6afc-4456-a9f0-3aa7ab7c31a6", "tokenUpdateTime":"2020-04-18 15:03:10" } } ``` # 商店目前開放可以抓取寵物清單取得 ## Cmd=shopMonsterListGet 請求封包格式 | 欄位 | 資料型態 | 內容 | | -------- | -------- | -------- | | sys | string | 系統(system)或遊戲(game) | | cmd | string | 封包名稱 shop_monster_list_get | | isEncode | bool | 加密與否 | | data | Obj | 封包資料 | | platformId | int | 平台編號 | | account | string | 帳號 | | userId | int | 會員流水編號 | ```json= { "sys":"game", "cmd":"shopMonsterListGet", "sn":12345, "isEncode":false, "data":{ "platformId":1, "account":"cat111", "userId":1 } } ``` 回應封包格式 | 欄位 | 資料型態 | 內容 | | -------- | -------- | -------- | | evolutionData | Array | 怪物進化分裂列表 | | enable | bool | 寵物是否啟用 | | monsterNo | number | 寵物編號 | | costMin | float | 最小價格 | | costMax | float | 最大價格 | | reservationCost | float | 預約消耗燃油(手續費) | | driveCost | float | 駕駛消耗燃油 | | getCoin | float | 可挖SOLO幣 | | shopMoney | float | 商城購物金 | | endDay | number | 結束天數 | | incomePercent | float | 收益總趴數 (EndDay N天結束後的總趴數) | | incomePercentByDay | float | 收益日趴數(IncomePercent/EndDay) | | userId | number | 會員編號(持有者) | | account | string | 帳號(持有者) | | reservationUserID | number | 會員編號(預約者) | | reservationAccount | string | 帳號(預約者) | | reservationTime | string | 紀錄預約時間, timeout 時, 就把預約者改回空白 | | createTime | string | 紀錄生產寵物時間 | | costNow | float | 目前價格 ( 超過CostMax 會進化拆分成N隻寵物 ) | | alive | bool | 是否存活著 (釋放後或過期就是false, 寵物持有中就是true) | | reservationKind | number | 預約種類 0: unknow 1:指定預約 2:隨機預約 3:隨機預約-開始 4:隨機預約-搶輸 5:此預約處理完畢 | | orderState | number | 寵物狀態, ORDER_STATE_EVOLUTION 代表以進化後的靜止寵物, 所以可以繼 | | orderId | string | 物此訂單的訂單Id | | serialNumber | number | 寵物的流水序號 | | dayCount | number | 累積了多少天 | | buyNotifyCheck | bool | 是否核對此寵物已付款, 如果已經付款就可以賣人(玩家預約買寵物, 匯款給某人, 拍照上傳, GM或持有人再去核對資料, 核對完畢就 BuyNotifyCheck=true) | ```json= { "code":0, "message":"回應成功阿", "sys":"game", "clientId":0, "sn":0, "isEncode":false, "ver":0, "ret":"shopMonsterListGet", "data":{ "storeMonsterList":[ { "evolutionData":null, "enable":true, "monsterNo":0, "name":"藍色勇士", "costMin":55, "costMax":300, "reservationCost":[3,5], "driveCost":1, "getCoin":1, "shopMoney":10, "endDay":3, "incomePercent":17, "incomePercentByDay":5.67, "userId":0, "account":"", "reservationUserID":0, "reservationAccount":"", "reservationTime":0, "costNow":55, "alive":true, "reservationKind":2, "orderState":1, "orderId":"", "serialNumber":0, "dayCount":0, "buyNotifyCheck":false }, { "evolutionData":null, "enable":true, "monsterNo":1, "name":"黃色鎧甲", "costMin":300, "costMax":600, "reservationCost":[11,15], "driveCost":1, "getCoin":1, "shopMoney":10, "endDay":5, "incomePercent":19, "incomePercentByDay":3.8, "userId":0, "account":"", "reservationUserID":0, "reservationAccount":"", "reservationTime":0, "costNow":300, "alive":true, "reservationKind":2, "orderState":1, "orderId":"", "serialNumber":1, "dayCount":0, "buyNotifyCheck":false } ] } } ``` # 商店已上架的寵物清單取得 ## Cmd=shopMonsterListAllGet 請求封包格式 | 欄位 | 資料型態 | 內容 | | -------- | -------- | -------- | | sys | string | 系統(system)或遊戲(game) | | cmd | string | 封包名稱 shop_monster_list_get | | isEncode | bool | 加密與否 | | data | Obj | 封包資料 | | platformId | int | 平台編號 | | account | string | 帳號 | | userId | int | 會員流水編號 | ```json= { "sys":"game", "cmd":"shopMonsterListAllGet", "sn":12345, "isEncode":false, "data":{ "platformId":1, "account":"cat111", "userId":1 } } ``` 回應封包格式 同商城清單(shopMonsterListGet) # 預約寵物清單取得 ## Cmd=shopMonsterReservationListGet 請求封包格式 | 欄位 | 資料型態 | 內容 | | -------- | -------- | -------- | | sys | string | 系統(system)或遊戲(game) | | cmd | string | 封包名稱 shop_monster_list_get | | isEncode | bool | 加密與否 | | data | Obj | 封包資料 | | platformId | int | 平台編號 | | account | string | 帳號 | | userId | int | 會員流水編號 | ```json= { "sys":"game", "cmd":"shopMonsterReservationListGet", "sn":12345, "isEncode":false, "data":{ "platformId":1, "account":"cat111", "userId":1 } } ``` 回應封包格式 同商城清單(shopMonsterListGet) ```json= { "code":0, "message":"回應成功阿", "sys":"game", "clientId":0, "sn":0, "isEncode":false, "ver":0, "ret":"shopMonsterReservationListGet", "data":{ "storeMonsterList":[ { "evolutionData":null, "enable":true, "monsterNo":0, "name":"藍色勇士", "costMin":55, "costMax":300, "reservationCost":[3,5], "driveCost":1, "getCoin":1, "shopMoney":10, "endDay":3, "incomePercent":17, "incomePercentByDay":5.67, "userId":0, "account":"", "reservationUserID":0, "reservationAccount":"", "reservationTime":0, "costNow":55, "alive":true, "reservationKind":2, "orderState":1, "orderId":"", "serialNumber":0, "dayCount":0, "buyNotifyCheck":false }, { "evolutionData":null, "enable":true, "monsterNo":1, "name":"黃色鎧甲", "costMin":300, "costMax":600, "reservationCost":[11,15], "driveCost":1, "getCoin":1, "shopMoney":10, "endDay":5, "incomePercent":19, "incomePercentByDay":3.8, "userId":0, "account":"", "reservationUserID":0, "reservationAccount":"", "reservationTime":0, "costNow":300, "alive":true, "reservationKind":2, "orderState":1, "orderId":"", "serialNumber":1, "dayCount":0, "buyNotifyCheck":false } ] } } ``` # 玩家背包寵物清單取得 ## Cmd=shopMonsterBagListGet 請求封包格式 | 欄位 | 資料型態 | 內容 | | -------- | -------- | -------- | | sys | string | 系統(system)或遊戲(game) | | cmd | string | 封包名稱 shop_monster_list_get | | isEncode | bool | 加密與否 | | data | Obj | 封包資料 | | platformId | int | 平台編號 | | account | string | 帳號 | | userId | int | 會員流水編號 | ```json= { "sys":"game", "cmd":"shopMonsterBagListGet", "sn":12345, "isEncode":false, "data":{ "platformId":1, "account":"cat111", "userId":1 } } ``` 回應封包格式 同商城清單(shopMonsterListGet) ```json= { "code":0, "message":"回應成功阿", "sys":"game", "clientId":0, "sn":0, "isEncode":false, "ver":0, "ret":"shopMonsterBagListGet", "data":{ "storeMonsterList":[ { "evolutionData":null, "enable":true, "monsterNo":0, "name":"藍色勇士", "costMin":55, "costMax":300, "reservationCost":[3,5], "driveCost":1, "getCoin":1, "shopMoney":10, "endDay":3, "incomePercent":17, "incomePercentByDay":5.67, "userId":0, "account":"", "reservationUserID":0, "reservationAccount":"", "reservationTime":0, "costNow":55, "alive":true, "reservationKind":2, "orderState":1, "orderId":"", "serialNumber":0, "dayCount":0, "buyNotifyCheck":false }, { "evolutionData":null, "enable":true, "monsterNo":1, "name":"黃色鎧甲", "costMin":300, "costMax":600, "reservationCost":[11,15], "driveCost":1, "getCoin":1, "shopMoney":10, "endDay":5, "incomePercent":19, "incomePercentByDay":3.8, "userId":0, "account":"", "reservationUserID":0, "reservationAccount":"", "reservationTime":0, "costNow":300, "alive":true, "reservationKind":2, "orderState":1, "orderId":"", "serialNumber":1, "dayCount":0, "buyNotifyCheck":false } ] } } ``` # 指定預約寵物 ## Cmd=shopMonsterAssignReservation 請求封包格式 | 欄位 | 資料型態 | 內容 | | -------- | -------- | -------- | | sys | string | 系統(system)或遊戲(game) | | cmd | string | 封包名稱 | | isEncode | bool | 加密與否 | | data | Obj | 封包資料 | | monsterNo | int | 寵物種類編號 | | serialNumber | int | 寵物流水編號 | | account | string | 帳號(持有者) | | userId | int | 會員流水編號(持有者) | | reservationAccount | string | 帳號(預約者) | | reservationUserID | int | 會員流水編號(預約者)| ```json= { "sys":"game", "cmd":"shopMonsterAssignReservation", "sn":12345, "isEncode":false, "data":{ "monsterNo":0, "serialNumber":1, "account":"cat111", "userId":1, "reservationAccount":"dog111", "reservationUserID": 789 } } ``` 回應封包格式 同商城清單(shopMonsterListGet) ```json= { "code":0, "message":"回應成功阿", "sys":"game", "clientId":0, "sn":0, "isEncode":false, "ver":0, "ret":"shopMonsterAssignReservation", "data":{ "shopMonster":{ "evolutionData":null, "enable":true, "monsterNo":1, "name":"黃色鎧甲", "costMin":300, "costMax":600, "reservationCost":[11,15], "driveCost":1, "getCoin":1, "shopMoney":10, "endDay":5, "incomePercent":19, "incomePercentByDay":3.8, "account":"", "reservationAccount":"", "reservationTime":0, "costNow":300, "alive":true, "orderState":1, "orderId":"", "serialNumber":1, "dayCount":0, "buyNotifyCheck":false } } } ``` # 隨機預約寵物 ## Cmd=shopMonsterRandomReservation 請求封包格式 | 欄位 | 資料型態 | 內容 | | -------- | -------- | -------- | | sys | string | 系統(system)或遊戲(game) | | cmd | string | 封包名稱 | | isEncode | bool | 加密與否 | | data | Obj | 封包資料 | | monsterNo | int | 寵物種類編號 | | account | string | 帳號(自己檢核用) | | userId | int | 會員流水編號(自己檢核用) | ```json= { "sys":"game", "cmd":"shopMonsterRandomReservation", "sn":12345, "isEncode":false, "data":{ "monsterNo":1, "account":"cat111", "userId":1 } } ``` 回應封包格式 同商城清單(shopMonsterListGet) ```json= { "code":0, "message":"回應成功阿", "sys":"game", "clientId":0, "sn":0, "isEncode":false, "ver":0, "ret":"shopMonsterRandomReservation", "data":{ "shopMonster":{ "evolutionData":null, "enable":true, "monsterNo":1, "name":"黃色鎧甲", "costMin":300, "costMax":600, "reservationCost":[11,15], "driveCost":1, "getCoin":1, "shopMoney":10, "endDay":5, "incomePercent":19, "incomePercentByDay":3.8, "account":"", "reservationAccount":"", "reservationTime":0, "costNow":300, "alive":true, "orderState":1, "orderId":"", "serialNumber":1, "dayCount":0, "buyNotifyCheck":false } } } ``` # 收到玩家的匯款後, 辦理寵物資料轉移(GM送過來) ## Cmd=shopMonsterReservationCheckFromGM 請求封包格式 | 欄位 | 資料型態 | 內容 | | -------- | -------- | -------- | | sys | string | 系統(system)或遊戲(game) | | cmd | string | 封包名稱 | | isEncode | bool | 加密與否 | | data | Obj | 封包資料 | | monsterNo | int | 寵物種類編號 | | serialNumber | int | 寵物流水編號 | | account | string | 帳號(持有者) | | userId | int | 會員流水編號(持有者) | | reservationAccount | string | 帳號(預約者) | | reservationUserID | int | 會員流水編號(預約者) | ```json= { "sys":"game", "cmd":"shopMonsterReservationCheckFromGM", "sn":12345, "isEncode":false, "data":{ "monsterNo":0, "serialNumber":1, "account":"cat111", "userId":1, "reservationAccount":"cat222", "reservationUserID":2 } } ``` 回應封包格式 同商城清單(shopMonsterListGet) ```json= { "code":0, "message":"回應成功阿", "sys":"game", "clientId":0, "sn":0, "isEncode":false, "ver":0, "ret":"shopMonsterReservationCheckFromGM", "data":{ "shopMonster":{ "evolutionData":null, "enable":true, "monsterNo":1, "name":"黃色鎧甲", "costMin":300, "costMax":600, "reservationCost":[11,15], "driveCost":1, "getCoin":1, "shopMoney":10, "endDay":5, "incomePercent":19, "incomePercentByDay":3.8, "account":"", "reservationAccount":"", "reservationTime":0, "costNow":300, "alive":true, "orderState":1, "orderId":"", "serialNumber":1, "dayCount":0, "buyNotifyCheck":false } } } ``` # 收到玩家的匯款後, 辦理寵物資料轉移(玩家送過來) ## Cmd=shopMonsterReservationCheckFromPlayer 請求封包格式 | 欄位 | 資料型態 | 內容 | | -------- | -------- | -------- | | sys | string | 系統(system)或遊戲(game) | | cmd | string | 封包名稱 | | isEncode | bool | 加密與否 | | data | Obj | 封包資料 | | monsterNo | int | 寵物種類編號 | | serialNumber | int | 寵物流水編號 | | account | string | 帳號(持有者) | | userId | int | 會員流水編號(持有者) | | reservationAccount | string | 帳號(預約者) | | reservationUserID | int | 會員流水編號(預約者) | ```json= { "sys":"game", "cmd":"shopMonsterReservationCheckFromPlayer", "sn":12345, "isEncode":false, "data":{ "monsterNo":1, "serialNumber":1, "account":"cat111", "userId":1, "reservationAccount":"cat222", "reservationUserID":2 } } ``` 回應封包格式 同商城清單(shopMonsterListGet) ```json= { "code":0, "message":"回應成功阿", "sys":"game", "clientId":0, "sn":0, "isEncode":false, "ver":0, "ret":"shopMonsterReservationCheckFromPlayer", "data":{ "shopMonster":{ "evolutionData":null, "enable":true, "monsterNo":1, "name":"黃色鎧甲", "costMin":300, "costMax":600, "reservationCost":[11,15], "driveCost":1, "getCoin":1, "shopMoney":10, "endDay":5, "incomePercent":19, "incomePercentByDay":3.8, "account":"", "reservationAccount":"", "reservationTime":0, "costNow":300, "alive":true, "orderState":1, "orderId":"", "serialNumber":1, "dayCount":0, "buyNotifyCheck":false } } } ``` # 模擬過一天 ## Cmd=simulationDay 請求封包格式 | 欄位 | 資料型態 | 內容 | | -------- | -------- | -------- | | sys | string | 系統(system)或遊戲(game) | | cmd | string | 封包名稱 | | isEncode | bool | 加密與否 | | data | Obj | 封包資料 | | account | string | 帳號 | | userId | int | 會員流水編號 | ```json= { "sys":"game", "cmd":"simulationDay", "sn":12345, "isEncode":false, "data":{ "account":"cat111", "userId":1 } } ``` 回應封包格式 | 欄位 | 資料型態 | 內容 | | -------- | -------- | -------- | | day | number | 目前過了幾天 | ```json= { "code":0, "message":"回應成功阿", "sys":"game", "clientId":0, "sn":0, "isEncode":false, "ver":0, "ret":"simulationDay", "data":{ "day":0 } } ``` # GM增加寵物一批 ## Cmd=shopMonsterGmAdd 請求封包格式 | 欄位 | 資料型態 | 內容 | | -------- | -------- | -------- | | sys | string | 系統(system)或遊戲(game) | | cmd | string | 封包名稱 | | isEncode | bool | 加密與否 | | data | Obj | 封包資料 | | account | string | 帳號 | | userId | int | 會員流水編號 | | monsterNoList | Array[int] | 上架怪物編號 | ```json= { "sys":"game", "cmd":"shopMonsterGmAdd", "sn":12345, "isEncode":false, "data":{ "account":"cat111", "userId":1, "monsterNoList":[1,2,3,4,5] } } ``` 回應封包格式 | 欄位 | 資料型態 | 內容 | | -------- | -------- | -------- | | day | number | 目前過了幾天 | ```json= { "code":0, "message":"回應成功阿", "sys":"game", "clientId":0, "sn":0, "isEncode":false, "ver":0, "ret":"shopMonsterGmAdd", "data":{ "monsterNoList":[1,2,3,4,5] } } ``` # 商店狀態取得 ## Cmd=shopStatusGet 請求封包格式 | 欄位 | 資料型態 | 內容 | | -------- | -------- | -------- | | sys | string | 系統(system)或遊戲(game) | | cmd | string | 封包名稱 | | isEncode | bool | 加密與否 | | data | Obj | 封包資料 | | account | string | 帳號 | | userId | int | 會員流水編號 | ```json= { "sys":"game", "cmd":"shopStatusGet", "sn":12345, "isEncode":false, "data":{ "account":"cat111", "userId":1 } } ``` 回應封包格式 | 欄位 | 資料型態 | 內容 | | -------- | -------- | -------- | | shopStatus | number | 0: wait 1:配對中 2:配對完畢 3:錯誤 4:維修中 | | day | number | 遊戲天數 | | playerCount | number | 玩家數量 | | storeMonsterCount | number | 寵物數量 | | dayBuyMonsterCnt | number | 日購買數量 | | dayEvolutionCnt | number | 進化分裂數量 | | dayUpgradeCnt | number | 升級數量 | | dayExpiredToShopCnt | number | 過期數量 | ```json= { "code":0, "message":"回應成功阿", "sys":"game", "clientId":0, "sn":0, "isEncode":false, "ver":0, "ret":"shopStatusGet", "data":{ "shopStatus":1, "day":10, "playerCount": 3, "storeMonsterCount":7, "dayBuyMonsterCnt":0, "dayEvolutionCnt":0, "dayUpgradeCnt":0, "dayExpiredToShopCnt":0 } } ``` # 商店狀態取得 ## Cmd=shopMaintain 請求封包格式 | 欄位 | 資料型態 | 內容 | | -------- | -------- | -------- | | sys | string | 系統(system)或遊戲(game) | | cmd | string | 封包名稱 | | isEncode | bool | 加密與否 | | data | Obj | 封包資料 | | account | string | GM帳號 | | userId | int | GM會員流水編號 | | isMainTain | bool | true:維修 false:開始遊戲 | ```json= { "sys":"game", "cmd":"shopMaintain", "sn":12345, "isEncode":false, "data":{ "account":"cat111", "userId":1, "isMainTain":true } } ``` 回應封包格式 | 欄位 | 資料型態 | 內容 | | -------- | -------- | -------- | | shopStatus | number | 0: wait 1:配對中 2:配對完畢 3:錯誤 4:維修中 | | day | number | 遊戲天數 | ```json= { "code":0, "message":"回應成功阿", "sys":"game", "clientId":0, "sn":0, "isEncode":false, "ver":0, "ret":"shopMaintain", "data":{ "shopStatus":1, "day":10 } } ``` # 使用流程 1.CreateAccount 建立一個帳號 2.Login 取得會員資料 (拿到 UserId + Account) 3.shopMonsterListGet 商店已上架的寵物清單取得 4.shopMonsterAssignReservation 指定預約寵物 ~~5.shopMonsterReservationCheckFromGM (GM送過來) <----剛開服 玩家剛買寵物, 需要有GM去檢查玩家是否有匯款 確認完畢後, 送此封包來~~ ~~6.shopMonsterBuy 玩家買寵物 ( 要先預約寵物後(不論是隨機預約寵物, 或指定預約寵物, 才可以使用此封包購買寵物 )~~