lijiali vor 2 Jahren
Commit
9e53022dad
84 geänderte Dateien mit 15861 neuen und 0 gelöschten Zeilen
  1. 18 0
      .gitignore
  2. 19 0
      .vscode/launch.json
  3. 0 0
      Bin/Config/dictionary.txt
  4. 30 0
      Bin/Scp/Item.csv
  5. 54 0
      Bin/Scp/Level.csv
  6. 64 0
      Bin/Scp/Role.csv
  7. 404 0
      Bin/Scp/RoleLevel.csv
  8. 86 0
      Bin/Scp/Sz.csv
  9. 23 0
      Bin/run.sh
  10. 22 0
      Dockerfile
  11. 394 0
      Proto/Message.proto
  12. 71 0
      Proto/MessageID.proto
  13. 34 0
      Server/Base/AutoInc.go
  14. 58 0
      Server/Base/CsvReader.go
  15. 9 0
      Server/Base/Interface.go
  16. 82 0
      Server/Base/Log/LineFormatter.go
  17. 62 0
      Server/Base/Log/Log.go
  18. 47 0
      Server/Base/Log/RotateHook.go
  19. 103 0
      Server/Base/Mysql.go
  20. 40 0
      Server/Base/Net.go
  21. 31 0
      Server/Base/Random.go
  22. 33 0
      Server/Base/Redis.go
  23. 177 0
      Server/Base/Sensitive/sensitive.go
  24. 165 0
      Server/Base/ServerBase.go
  25. 25 0
      Server/Base/Service/Def.go
  26. 113 0
      Server/Base/Service/Service.go
  27. 24 0
      Server/Base/SpinLock.go
  28. 40 0
      Server/Base/TcpCodec.go
  29. 176 0
      Server/Base/Timer.go
  30. 108 0
      Server/Base/Util.go
  31. 39 0
      Server/Base/WebCodec.go
  32. 23 0
      Server/Common/GlobalDef.go
  33. 14 0
      Server/Config/dev.conf
  34. 0 0
      Server/Config/dictionary.txt
  35. 14 0
      Server/Config/test.conf
  36. BIN
      Server/GameServer/GameServer
  37. BIN
      Server/GameServer/Main
  38. 11 0
      Server/GameServer/Main.go
  39. 22 0
      Server/GameServer/Server/DB/DBDef.go
  40. 32 0
      Server/GameServer/Server/DB/DBOperation.go
  41. 130 0
      Server/GameServer/Server/Logic/Execute.go
  42. 62 0
      Server/GameServer/Server/Logic/Gm.go
  43. 113 0
      Server/GameServer/Server/Logic/LogicMgr.go
  44. 69 0
      Server/GameServer/Server/Logic/Player.go
  45. 80 0
      Server/GameServer/Server/Logic/PlayerMgr.go
  46. 32 0
      Server/GameServer/Server/Logic/Room.go
  47. 96 0
      Server/GameServer/Server/Logic/RoomMgr.go
  48. 231 0
      Server/GameServer/Server/PlaneGame/GmWeb/Http.go
  49. 55 0
      Server/GameServer/Server/PlaneGame/GmWeb/Mgr.go
  50. 120 0
      Server/GameServer/Server/PlaneGame/GmWeb/Sw.go
  51. 34 0
      Server/GameServer/Server/PlaneGame/Module/Db.go
  52. 1655 0
      Server/GameServer/Server/PlaneGame/Module/Plane.go
  53. 1737 0
      Server/GameServer/Server/PlaneGame/Module/Player.go
  54. 901 0
      Server/GameServer/Server/PlaneGame/Module/Room.go
  55. 10 0
      Server/GameServer/Server/PlaneGame/Utils/CsvReaderUtil.go
  56. 225 0
      Server/GameServer/Server/PlaneGame/Utils/HttpUtil.go
  57. 118 0
      Server/GameServer/Server/Server.go
  58. 4947 0
      Server/Message/Message.pb.go
  59. 362 0
      Server/Message/MessageID.pb.go
  60. 27 0
      Server/Scheme/SchemeDef.go
  61. 89 0
      Server/Scheme/SchemeItem.go
  62. 74 0
      Server/Scheme/SchemeLevel.go
  63. 27 0
      Server/Scheme/SchemeMgr.go
  64. 58 0
      Server/Scheme/SchemeRole.go
  65. 62 0
      Server/Scheme/SchemeRoleLevel.go
  66. 117 0
      Server/Scheme/SchemeSz.go
  67. 30 0
      Server/Scp/Item.csv
  68. 54 0
      Server/Scp/Level.csv
  69. 64 0
      Server/Scp/Role.csv
  70. 404 0
      Server/Scp/RoleLevel.csv
  71. 86 0
      Server/Scp/Sz.csv
  72. 29 0
      Tools/Web/websockets_json.html
  73. 24 0
      Tools/Web/websockets_string.html
  74. 4 0
      Tools/buildPB.bat
  75. 2 0
      Tools/buildPB.sh
  76. BIN
      Tools/conf/conf
  77. 191 0
      Tools/conf/generator.go
  78. 113 0
      Tools/conf/main.go
  79. 34 0
      Tools/game.sql
  80. 36 0
      Tools/offlineData/main.go
  81. 15 0
      build.sh
  82. 32 0
      go.mod
  83. 633 0
      go.sum
  84. 12 0
      readme.md

+ 18 - 0
.gitignore

@@ -0,0 +1,18 @@
+# common IDE files
+**/.settings
+**/*.log
+# happy build files
+**/Bin/Log/
+**/Bin/GameServer/
+**/Bin/GameServer/
+**/Bin/Tools/
+**/Bin/Config/*.conf
+**/.idea
+.idea
+
+/Server/GameServer/pkg/**
+/Web/**
+/Test/**
+**/*.exe
+
+

+ 19 - 0
.vscode/launch.json

@@ -0,0 +1,19 @@
+{
+    // 使用 IntelliSense 了解相关属性。 
+    // 悬停以查看现有属性的描述。
+    // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
+    "version": "0.2.0",
+    "configurations": [
+
+        {
+            "name": "Launch",
+            "type": "go",
+            "request": "launch",
+            "mode": "auto",
+          //  "program": "${workspaceFolder}/Server/GameServer",
+           "program": "${workspaceFolder}/Test",
+            "env": {},
+            "args": []
+        }
+    ]
+}

Datei-Diff unterdrückt, da er zu groß ist
+ 0 - 0
Bin/Config/dictionary.txt


+ 30 - 0
Bin/Scp/Item.csv

@@ -0,0 +1,30 @@
+索引,品质,物品类型,类型参数,价值
+INT,INT,STRING,INT,INT
+32,32,256,32,32
+id,quality,type,value,price
+1,0,Item,0,2
+2,0,Item,0,100
+4,0,Item,0,1
+5,0,Item,0,1000
+6,0,Item,0,1
+101,0,Gift,302,1
+102,0,Item,0,500
+103,0,Item,0,1
+104,0,Item,0,1000
+105,0,Item,0,1000
+106,0,Item,0,1000
+107,0,Item,0,1000
+108,0,Item,0,1000
+201,0,Item,0,8000
+202,0,Item,0,30000
+301,0,Item,0,5000
+400,0,Gift,301,10000
+401,0,Item,0,10000
+402,0,Item,0,10000
+403,0,Item,0,10000
+404,0,Item,0,10000
+501,1,Gift,201,10000
+502,2,Gift,202,10000
+503,3,Gift,203,10000
+504,4,Gift,204,10000
+505,5,Gift,205,10000

+ 54 - 0
Bin/Scp/Level.csv

@@ -0,0 +1,54 @@
+等级,升至下级所需经验,英雄等级上限,体力上限,体力储存上限,升至本级的奖励
+INT,INT,INT,INT,INT,STRING
+32,32,32,32,32,256
+level,exp,heroMaxLevel,maxEnergy,maxStorageEnergy,levelPrize
+1,100,4,30,300,
+2,150,8,30,300,Item_2_20
+3,200,12,30,300,Item_2_20
+4,250,16,30,300,Item_2_20
+5,300,20,30,300,Item_2_20
+6,350,24,30,300,Item_2_20
+7,400,28,30,300,Item_2_20
+8,500,32,30,300,Item_2_20
+9,600,36,30,300,Item_2_20
+10,700,40,30,300,Item_2_20
+11,800,44,30,300,Item_2_20
+12,900,48,30,300,Item_2_20
+13,1000,52,30,300,Item_2_20
+14,1100,56,30,300,Item_2_20
+15,1300,60,30,300,Item_2_20
+16,1500,64,30,300,Item_2_20
+17,1700,68,30,300,Item_2_20
+18,1900,72,30,300,Item_2_20
+19,2100,76,30,300,Item_2_20
+20,2300,80,30,300,Item_2_20
+21,2500,84,30,300,Item_2_20
+22,2900,88,30,300,Item_2_20
+23,3300,92,30,300,Item_2_20
+24,3700,96,30,300,Item_2_20
+25,4100,100,30,300,Item_2_20
+26,4500,104,30,300,Item_2_20
+27,4900,108,30,300,Item_2_20
+28,5300,112,30,300,Item_2_20
+29,6100,116,30,300,Item_2_20
+30,6900,120,30,300,Item_2_20
+31,7700,124,30,300,Item_2_20
+32,8500,128,30,300,Item_2_20
+33,9300,132,30,300,Item_2_20
+34,10100,136,30,300,Item_2_20
+35,10900,140,30,300,Item_2_20
+36,12500,144,30,300,Item_2_20
+37,14100,148,30,300,Item_2_20
+38,15700,152,30,300,Item_2_20
+39,17300,156,30,300,Item_2_20
+40,18900,160,30,300,Item_2_20
+41,20500,164,30,300,Item_2_20
+42,22100,168,30,300,Item_2_20
+43,25300,172,30,300,Item_2_20
+44,28500,176,30,300,Item_2_20
+45,31700,180,30,300,Item_2_20
+46,34900,184,30,300,Item_2_20
+47,38100,188,30,300,Item_2_20
+48,41300,192,30,300,Item_2_20
+49,44500,196,30,300,Item_2_20
+50,47700,200,30,300,Item_2_20

+ 64 - 0
Bin/Scp/Role.csv

@@ -0,0 +1,64 @@
+英雄Id
+INT
+32
+id
+1
+2
+3
+4
+11
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1010
+1011
+1101
+1103
+1105
+1201
+1205
+1210
+2001
+2002
+2003
+2004
+2005
+2006
+2007
+2008
+2009
+2010
+2011
+2012
+2013
+2014
+2016
+2017
+2105
+2110
+3001
+3002
+3003
+3004
+3005
+3006
+3007
+3010
+3105
+4001
+4002
+4003
+4005
+4006
+4007
+4012
+4013
+4014
+4015
+4016
+4017

+ 404 - 0
Bin/Scp/RoleLevel.csv

@@ -0,0 +1,404 @@
+序号,英雄Id,英雄等级,升级消耗
+INT,INT,INT,STRING
+32,32,32,256
+id,role,level,cost
+1,1,1,Item_1_100
+2,1,2,Item_1_120
+3,1,3,Item_1_140
+4,1,4,Item_1_160
+5,1,5,Item_1_180
+6,1,6,Item_1_200
+7,1,7,Item_1_220
+8,1,8,Item_1_240
+9,1,9,Item_1_260
+10,1,10,Item_1_280
+11,1,11,Item_1_300
+12,1,12,Item_1_320
+13,1,13,Item_1_340
+14,1,14,Item_1_380
+15,1,15,Item_1_420
+16,1,16,Item_1_460
+17,1,17,Item_1_500
+18,1,18,Item_1_540
+19,1,19,Item_1_580
+20,1,20,Item_1_620
+21,1,21,Item_1_660
+22,1,22,Item_1_700
+23,1,23,Item_1_740
+24,1,24,Item_1_780
+25,1,25,Item_1_820
+26,1,26,Item_1_860
+27,1,27,Item_1_900
+28,1,28,Item_1_980
+29,1,29,Item_1_1060
+30,1,30,Item_1_1140
+31,1,31,Item_1_1220
+32,1,32,Item_1_1300
+33,1,33,Item_1_1380
+34,1,34,Item_1_1460
+35,1,35,Item_1_1540
+36,1,36,Item_1_1620
+37,1,37,Item_1_1700
+38,1,38,Item_1_1780
+39,1,39,Item_1_1860
+40,1,40,Item_1_1940
+41,1,41,Item_1_2020
+42,1,42,Item_1_2180
+43,1,43,Item_1_2340
+44,1,44,Item_1_2500
+45,1,45,Item_1_2660
+46,1,46,Item_1_2820
+47,1,47,Item_1_2980
+48,1,48,Item_1_3140
+49,1,49,Item_1_3300
+50,1,50,Item_1_3460
+51,1,51,Item_1_3620
+52,1,52,Item_1_3780
+53,1,53,Item_1_3940
+54,1,54,Item_1_4100
+55,1,55,Item_1_4260
+56,1,56,Item_1_4420
+57,1,57,Item_1_4740
+58,1,58,Item_1_5060
+59,1,59,Item_1_5380
+60,1,60,Item_1_5700
+61,1,61,Item_1_6020
+62,1,62,Item_1_6340
+63,1,63,Item_1_6660
+64,1,64,Item_1_6980
+65,1,65,Item_1_7300
+66,1,66,Item_1_7620
+67,1,67,Item_1_7940
+68,1,68,Item_1_8260
+69,1,69,Item_1_8580
+70,1,70,Item_1_8900
+71,1,71,Item_1_9540
+72,1,72,Item_1_10180
+73,1,73,Item_1_10820
+74,1,74,Item_1_11460
+75,1,75,Item_1_12100
+76,1,76,Item_1_12740
+77,1,77,Item_1_13380
+78,1,78,Item_1_14020
+79,1,79,Item_1_14660
+80,1,80,Item_1_15300
+81,1,81,Item_1_15940
+82,1,82,Item_1_16580
+83,1,83,Item_1_17220
+84,1,84,Item_1_17860
+85,1,85,Item_1_19140
+86,1,86,Item_1_20420
+87,1,87,Item_1_21700
+88,1,88,Item_1_22980
+89,1,89,Item_1_24260
+90,1,90,Item_1_25540
+91,1,91,Item_1_26820
+92,1,92,Item_1_28100
+93,1,93,Item_1_29380
+94,1,94,Item_1_30660
+95,1,95,Item_1_31940
+96,1,96,Item_1_33220
+97,1,97,Item_1_34500
+98,1,98,Item_1_35780
+99,1,99,Item_1_37060
+100,1,100,0
+101,2,1,Item_1_100
+102,2,2,Item_1_120
+103,2,3,Item_1_140
+104,2,4,Item_1_160
+105,2,5,Item_1_180
+106,2,6,Item_1_200
+107,2,7,Item_1_220
+108,2,8,Item_1_240
+109,2,9,Item_1_260
+110,2,10,Item_1_280
+111,2,11,Item_1_300
+112,2,12,Item_1_320
+113,2,13,Item_1_340
+114,2,14,Item_1_380
+115,2,15,Item_1_420
+116,2,16,Item_1_460
+117,2,17,Item_1_500
+118,2,18,Item_1_540
+119,2,19,Item_1_580
+120,2,20,Item_1_620
+121,2,21,Item_1_660
+122,2,22,Item_1_700
+123,2,23,Item_1_740
+124,2,24,Item_1_780
+125,2,25,Item_1_820
+126,2,26,Item_1_860
+127,2,27,Item_1_900
+128,2,28,Item_1_980
+129,2,29,Item_1_1060
+130,2,30,Item_1_1140
+131,2,31,Item_1_1220
+132,2,32,Item_1_1300
+133,2,33,Item_1_1380
+134,2,34,Item_1_1460
+135,2,35,Item_1_1540
+136,2,36,Item_1_1620
+137,2,37,Item_1_1700
+138,2,38,Item_1_1780
+139,2,39,Item_1_1860
+140,2,40,Item_1_1940
+141,2,41,Item_1_2020
+142,2,42,Item_1_2180
+143,2,43,Item_1_2340
+144,2,44,Item_1_2500
+145,2,45,Item_1_2660
+146,2,46,Item_1_2820
+147,2,47,Item_1_2980
+148,2,48,Item_1_3140
+149,2,49,Item_1_3300
+150,2,50,Item_1_3460
+151,2,51,Item_1_3620
+152,2,52,Item_1_3780
+153,2,53,Item_1_3940
+154,2,54,Item_1_4100
+155,2,55,Item_1_4260
+156,2,56,Item_1_4420
+157,2,57,Item_1_4740
+158,2,58,Item_1_5060
+159,2,59,Item_1_5380
+160,2,60,Item_1_5700
+161,2,61,Item_1_6020
+162,2,62,Item_1_6340
+163,2,63,Item_1_6660
+164,2,64,Item_1_6980
+165,2,65,Item_1_7300
+166,2,66,Item_1_7620
+167,2,67,Item_1_7940
+168,2,68,Item_1_8260
+169,2,69,Item_1_8580
+170,2,70,Item_1_8900
+171,2,71,Item_1_9540
+172,2,72,Item_1_10180
+173,2,73,Item_1_10820
+174,2,74,Item_1_11460
+175,2,75,Item_1_12100
+176,2,76,Item_1_12740
+177,2,77,Item_1_13380
+178,2,78,Item_1_14020
+179,2,79,Item_1_14660
+180,2,80,Item_1_15300
+181,2,81,Item_1_15940
+182,2,82,Item_1_16580
+183,2,83,Item_1_17220
+184,2,84,Item_1_17860
+185,2,85,Item_1_19140
+186,2,86,Item_1_20420
+187,2,87,Item_1_21700
+188,2,88,Item_1_22980
+189,2,89,Item_1_24260
+190,2,90,Item_1_25540
+191,2,91,Item_1_26820
+192,2,92,Item_1_28100
+193,2,93,Item_1_29380
+194,2,94,Item_1_30660
+195,2,95,Item_1_31940
+196,2,96,Item_1_33220
+197,2,97,Item_1_34500
+198,2,98,Item_1_35780
+199,2,99,Item_1_37060
+200,2,100,0
+201,3,1,Item_1_100
+202,3,2,Item_1_120
+203,3,3,Item_1_140
+204,3,4,Item_1_160
+205,3,5,Item_1_180
+206,3,6,Item_1_200
+207,3,7,Item_1_220
+208,3,8,Item_1_240
+209,3,9,Item_1_260
+210,3,10,Item_1_280
+211,3,11,Item_1_300
+212,3,12,Item_1_320
+213,3,13,Item_1_340
+214,3,14,Item_1_380
+215,3,15,Item_1_420
+216,3,16,Item_1_460
+217,3,17,Item_1_500
+218,3,18,Item_1_540
+219,3,19,Item_1_580
+220,3,20,Item_1_620
+221,3,21,Item_1_660
+222,3,22,Item_1_700
+223,3,23,Item_1_740
+224,3,24,Item_1_780
+225,3,25,Item_1_820
+226,3,26,Item_1_860
+227,3,27,Item_1_900
+228,3,28,Item_1_980
+229,3,29,Item_1_1060
+230,3,30,Item_1_1140
+231,3,31,Item_1_1220
+232,3,32,Item_1_1300
+233,3,33,Item_1_1380
+234,3,34,Item_1_1460
+235,3,35,Item_1_1540
+236,3,36,Item_1_1620
+237,3,37,Item_1_1700
+238,3,38,Item_1_1780
+239,3,39,Item_1_1860
+240,3,40,Item_1_1940
+241,3,41,Item_1_2020
+242,3,42,Item_1_2180
+243,3,43,Item_1_2340
+244,3,44,Item_1_2500
+245,3,45,Item_1_2660
+246,3,46,Item_1_2820
+247,3,47,Item_1_2980
+248,3,48,Item_1_3140
+249,3,49,Item_1_3300
+250,3,50,Item_1_3460
+251,3,51,Item_1_3620
+252,3,52,Item_1_3780
+253,3,53,Item_1_3940
+254,3,54,Item_1_4100
+255,3,55,Item_1_4260
+256,3,56,Item_1_4420
+257,3,57,Item_1_4740
+258,3,58,Item_1_5060
+259,3,59,Item_1_5380
+260,3,60,Item_1_5700
+261,3,61,Item_1_6020
+262,3,62,Item_1_6340
+263,3,63,Item_1_6660
+264,3,64,Item_1_6980
+265,3,65,Item_1_7300
+266,3,66,Item_1_7620
+267,3,67,Item_1_7940
+268,3,68,Item_1_8260
+269,3,69,Item_1_8580
+270,3,70,Item_1_8900
+271,3,71,Item_1_9540
+272,3,72,Item_1_10180
+273,3,73,Item_1_10820
+274,3,74,Item_1_11460
+275,3,75,Item_1_12100
+276,3,76,Item_1_12740
+277,3,77,Item_1_13380
+278,3,78,Item_1_14020
+279,3,79,Item_1_14660
+280,3,80,Item_1_15300
+281,3,81,Item_1_15940
+282,3,82,Item_1_16580
+283,3,83,Item_1_17220
+284,3,84,Item_1_17860
+285,3,85,Item_1_19140
+286,3,86,Item_1_20420
+287,3,87,Item_1_21700
+288,3,88,Item_1_22980
+289,3,89,Item_1_24260
+290,3,90,Item_1_25540
+291,3,91,Item_1_26820
+292,3,92,Item_1_28100
+293,3,93,Item_1_29380
+294,3,94,Item_1_30660
+295,3,95,Item_1_31940
+296,3,96,Item_1_33220
+297,3,97,Item_1_34500
+298,3,98,Item_1_35780
+299,3,99,Item_1_37060
+300,3,100,0
+301,4,1,Item_1_100
+302,4,2,Item_1_120
+303,4,3,Item_1_140
+304,4,4,Item_1_160
+305,4,5,Item_1_180
+306,4,6,Item_1_200
+307,4,7,Item_1_220
+308,4,8,Item_1_240
+309,4,9,Item_1_260
+310,4,10,Item_1_280
+311,4,11,Item_1_300
+312,4,12,Item_1_320
+313,4,13,Item_1_340
+314,4,14,Item_1_380
+315,4,15,Item_1_420
+316,4,16,Item_1_460
+317,4,17,Item_1_500
+318,4,18,Item_1_540
+319,4,19,Item_1_580
+320,4,20,Item_1_620
+321,4,21,Item_1_660
+322,4,22,Item_1_700
+323,4,23,Item_1_740
+324,4,24,Item_1_780
+325,4,25,Item_1_820
+326,4,26,Item_1_860
+327,4,27,Item_1_900
+328,4,28,Item_1_980
+329,4,29,Item_1_1060
+330,4,30,Item_1_1140
+331,4,31,Item_1_1220
+332,4,32,Item_1_1300
+333,4,33,Item_1_1380
+334,4,34,Item_1_1460
+335,4,35,Item_1_1540
+336,4,36,Item_1_1620
+337,4,37,Item_1_1700
+338,4,38,Item_1_1780
+339,4,39,Item_1_1860
+340,4,40,Item_1_1940
+341,4,41,Item_1_2020
+342,4,42,Item_1_2180
+343,4,43,Item_1_2340
+344,4,44,Item_1_2500
+345,4,45,Item_1_2660
+346,4,46,Item_1_2820
+347,4,47,Item_1_2980
+348,4,48,Item_1_3140
+349,4,49,Item_1_3300
+350,4,50,Item_1_3460
+351,4,51,Item_1_3620
+352,4,52,Item_1_3780
+353,4,53,Item_1_3940
+354,4,54,Item_1_4100
+355,4,55,Item_1_4260
+356,4,56,Item_1_4420
+357,4,57,Item_1_4740
+358,4,58,Item_1_5060
+359,4,59,Item_1_5380
+360,4,60,Item_1_5700
+361,4,61,Item_1_6020
+362,4,62,Item_1_6340
+363,4,63,Item_1_6660
+364,4,64,Item_1_6980
+365,4,65,Item_1_7300
+366,4,66,Item_1_7620
+367,4,67,Item_1_7940
+368,4,68,Item_1_8260
+369,4,69,Item_1_8580
+370,4,70,Item_1_8900
+371,4,71,Item_1_9540
+372,4,72,Item_1_10180
+373,4,73,Item_1_10820
+374,4,74,Item_1_11460
+375,4,75,Item_1_12100
+376,4,76,Item_1_12740
+377,4,77,Item_1_13380
+378,4,78,Item_1_14020
+379,4,79,Item_1_14660
+380,4,80,Item_1_15300
+381,4,81,Item_1_15940
+382,4,82,Item_1_16580
+383,4,83,Item_1_17220
+384,4,84,Item_1_17860
+385,4,85,Item_1_19140
+386,4,86,Item_1_20420
+387,4,87,Item_1_21700
+388,4,88,Item_1_22980
+389,4,89,Item_1_24260
+390,4,90,Item_1_25540
+391,4,91,Item_1_26820
+392,4,92,Item_1_28100
+393,4,93,Item_1_29380
+394,4,94,Item_1_30660
+395,4,95,Item_1_31940
+396,4,96,Item_1_33220
+397,4,97,Item_1_34500
+398,4,98,Item_1_35780
+399,4,99,Item_1_37060
+400,4,100,0

+ 86 - 0
Bin/Scp/Sz.csv

@@ -0,0 +1,86 @@
+ds,weight,playerNum,finialPlane,finialArea,finialPoint
+INT,INT,INT,INT,INT,INT
+32,32,32,32,32,32
+ds,weight,playerNum,finialPlane,finialArea,finialPoint
+1,1400,2,2,2,0
+2,2800,2,2,2,0
+3,4200,2,2,2,0
+4,5600,2,2,2,0
+5,7000,2,2,2,0
+6,10000,2,2,2,0
+1,1400,2,1,1,0
+2,2800,2,1,1,0
+3,4200,2,1,1,0
+4,5600,2,1,1,0
+5,7000,2,1,1,0
+6,10000,2,1,1,0
+1,1000,1,2,2,0
+2,2000,1,2,2,0
+3,3500,1,2,2,0
+4,5000,1,2,2,0
+5,7000,1,2,2,0
+6,10000,1,2,2,0
+1,1400,1,1,2,0
+2,2800,1,1,2,0
+3,4200,1,1,2,0
+4,5600,1,1,2,0
+5,7000,1,1,2,0
+6,10000,1,1,2,0
+1,1000,1,1,1,1
+2,2500,1,1,1,1
+3,4000,1,1,1,1
+4,5500,1,1,1,1
+5,7000,1,1,1,1
+6,10000,1,1,1,1
+1,1500,1,1,1,2
+2,2500,1,1,1,2
+3,4000,1,1,1,2
+4,5500,1,1,1,2
+5,7000,1,1,1,2
+6,10000,1,1,1,2
+1,1500,1,1,1,3
+2,3000,1,1,1,3
+3,4500,1,1,1,3
+4,5500,1,1,1,3
+5,7000,1,1,1,3
+6,10000,1,1,1,3
+1,1500,1,1,1,4
+2,3000,1,1,1,4
+3,4000,1,1,1,4
+4,5500,1,1,1,4
+5,7000,1,1,1,4
+6,10000,1,1,1,4
+1,1500,1,1,1,5
+2,3000,1,1,1,5
+3,4500,1,1,1,5
+4,6000,1,1,1,5
+5,7000,1,1,1,5
+6,10000,1,1,1,5
+1,1800,1,1,1,6
+2,3600,1,1,1,6
+3,5400,1,1,1,6
+4,7200,1,1,1,6
+5,9000,1,1,1,6
+6,10000,1,1,1,6
+,,,,,
+,,,,,
+,,,,,
+,,,,,
+,,,,,
+,,,,,
+,,,,,
+,,,,,
+,,,,,
+,,,,,
+,,,,,
+,,,,,
+,,,,,
+,,,,,
+,,,,,
+,,,,,
+,,,,,
+,,云房数据拉房失败,数据回退,,,
+,,getuserinfo函数中需要判断是否是对应的玩家,才会更新游戏人数,,,
+,,游戏结束数据回传,,,
+,,掉线重连,会掉getuserinfo接口,,,
+,,房间id初始化,,,

+ 23 - 0
Bin/run.sh

@@ -0,0 +1,23 @@
+if [ $# -ne 2 ];
+then
+        echo "usage: sh run.sh [start|stop|restart] [test]"
+        exit 0
+fi
+
+ver=$2
+
+ulimit -c unlimited
+if [[ $1 == "stop" ]]; then
+        ps -ef | grep tag=${ver} | grep -v grep  | awk '{print $2}' | xargs kill -15
+elif [[ $1 == "start" ]]; then
+        cd GameServer
+        GOTRACEBACK=crash ./GameServer --tag=${ver} &
+elif [[ $1 == "restart" ]]; then
+        ps -ef | grep tag=${ver} | grep -v grep  | awk '{print $2}' | xargs kill -15
+        sleep 5s
+        cd GameServer
+        GOTRACEBACK=crash ./GameServer --tag=${ver} &
+else
+        echo "usage: sh run.sh [start|stop|restart] [test]"
+        exit 0
+fi

+ 22 - 0
Dockerfile

@@ -0,0 +1,22 @@
+FROM golang:1.19-alpine as builder
+
+ENV GOPROXY https://goproxy.cn
+ENV GO111MODULE on
+
+WORKDIR /go/cache
+
+ADD go.mod .
+ADD go.sum .
+RUN go mod download
+
+WORKDIR /go/release
+ADD . .
+WORKDIR /go/release/Server/GameServer
+RUN go build -o /go/release/Bin/GameServer/GameServer
+
+FROM alpine
+COPY --from=builder /go/release/Bin /release
+WORKDIR /release/GameServer
+
+EXPOSE 20001
+CMD ["./GameServer", "--tag=dev"]

+ 394 - 0
Proto/Message.proto

@@ -0,0 +1,394 @@
+syntax = "proto3";
+
+package BBMessage;
+option go_package = "./;message";
+
+// 通用操作结果码
+enum GameStatus {
+    GAME_STATUS_OK = 0;
+    GAME_STATUS_PLAYER_NIL = 1001; // 玩家不存在
+    GAME_STATUS_UID_PASSWD_NIL = 1002; // 账号或密码不能为空
+    GAME_STATUS_UID_ERROR = 1003; // 账号不存在
+    GAME_STATUS_PASSWD_ERROR = 1004; // 密码错误
+    GAME_STATUS_ROOM_NOT_EXIT = 1005; // 房间不存在
+    GAME_STATUS_PB_ERR = 1006;//协议解析报错
+    GAME_STATUS_INNER_ERR = 1007; // 服务器内部错误
+
+
+    GAME_STATUS_LOGIN_CHECK_ERR = 1055; // 登录校验失败
+    Player_Status_0=11;//表示玩家在大厅,
+    Player_Status_1=1;//表示玩家开始匹配,
+    Player_Status_2=2;//玩家进入游戏房间,
+    Player_Status_3=3;//ready,玩家落座开始游戏
+    Player_Status_4=4;//play,
+    Player_Status_5=5;//胜利后观战,
+    Player_Status_6=6;//胜利后离开,
+    Player_Status_7=7;//组队逃跑,
+    Player_Status_8=8;//逃跑,
+    Player_Status_9=9;//托管,
+    Player_Status_10=10;//观战玩家,
+    //GAME_STATUS_LOGIN_CHECK_ERR = 1055; // 登录校验失败
+
+}
+
+// 心跳包C->S, Cmd.MSGID_Heartbeat_Push(心跳包需要保持,不然玩家会被踢下线)
+message HeartbeatPush {
+
+}
+
+// 登录请求 C->S, Cmd.MSGID_Login
+message LoginReq {
+    string uid = 1;//账号ID
+    string passWd = 2;//密码
+}
+
+// 登录响应 S->C, Cmd.MSGID_Login
+message LoginRsp {
+    uint32 result = 1;//结果
+    int64 playerId = 2;//玩家ID
+    bool isNew = 3;//是否为新玩家
+}
+
+message CreateGameReq {
+    uint32 mode = 1;//游戏模式,1是经典,2是匹配
+    uint32 playerNum  = 2;//选择玩家人数  2是两个人,4是四个人
+    uint32 admissionFee  = 3;//入场金额   500、1000、2000、5000、10000、20000
+    bool isRoom  = 4;//是否房间内建房
+    string uid  = 5;//玩家id
+    string name  = 6;//玩家名称
+    string headImg  = 7;//玩家头像
+    optional uint32 money  = 8;//玩家金币
+     optional uint32 chatRoomId  = 9;//语聊房id
+
+}
+message CreateGameRsp {
+    optional uint32 roomId =1; //房间id
+    string uid =2; //用户id
+    string name  = 3;//玩家名称
+    string headImg  = 4;//玩家头像
+    optional uint32 money  = 5;//玩家金币
+}
+message RoomInfoRsp {
+    optional uint32 result = 1;//结果
+    repeated  uint32 money=2;
+    repeated string playerID =3;
+    repeated string nick=4; //昵称
+    repeated string headUrl =5; //头像
+     repeated uint32 seatId =9; //头像
+    uint32 mode = 6;//游戏模式,1是经典,2是匹配
+    uint32 playerNum  = 7;//选择玩家人数  2是两个人,4是四个人
+    uint32 admissionFee  = 8;//入场金额   500、1000、2000、5000、10000、20000
+     
+
+}
+
+message JoinRoomReq {
+     string uid = 1;//uID
+    string name  = 2;//玩家名称
+    string headImg  = 3;//玩家头像
+    optional uint32 money  = 4;//玩家金币
+    optional uint32 roomId  = 5;//房间id
+    bool restartBtn  = 6;//是否是restart点击
+}
+
+message RoomKickUserReq {
+    string uid = 1;//uID
+
+}
+message RoomKickUserRsp {
+    string uid = 1;//uID
+    string name  = 2;//玩家名称
+}
+message RoomQuitUserReq {
+    string uid = 1;//uID
+
+}
+
+message RoomInviteReq {
+    string uid = 1;//邀请的玩家id
+    optional uint32 chatRoomId = 2;//语聊房id
+    optional uint32 roomId = 3;//游戏房间id
+}
+message RoomInviteRsp {
+   optional uint32 result = 1;//结果
+
+}
+message RoomQuitUserRsp {
+    string uid = 1;//uID
+    string name  = 2;//玩家名称
+}
+message JoinRoomInfoRsp {
+    optional uint32 result = 1;//结果
+    string money=2;
+    string playerID =3;
+    uint32 playerStatus=4;  // 玩家的当前状态, 0、1 表示空位无玩家,2: sitdown, 3: ready, 4: play, 5: 胜利后观战, 6: 胜利后离开,7: 组队逃跑,8: 逃跑
+    uint32 tableID=5; // 桌子ID
+    optional uint32 seatID=6; //座位号
+    string nick=7; //昵称
+    string headUrl =8; //头像
+    string gender =9; //性别
+    optional uint32 playerNum=10;  // 玩家数量
+    uint32 playerType=11;  // 玩家类型1是正常玩家2是机器人
+}
+
+message RoomInfoReq {
+ optional uint32 roomId = 1;//房间id
+  string uid = 2;//玩家id
+}
+
+message CancelMatchReq {
+
+}
+message CancelMatchRsp {
+    optional uint32 result = 1;//结果0表示成功,其他表示失败
+    string uid = 2;//用户id
+}
+
+message MatchRsp {
+    optional uint32 result = 1;//结果  0表示成功,其他表示失败
+}
+message MatchJoinUserRsp {
+    optional uint32 result = 1;//结果
+    string playerID =2;
+    string nick=3; //昵称
+    string headUrl =4; //头像
+    string gender =5; //性别
+    uint32 playerNum=6;  // 玩家数量
+}
+
+
+message RoomStartGameReq {
+
+}
+message RoomStartGameRsp {
+
+}
+
+//获取玩家数据
+message GetUserInfoReq {
+    string uid = 1;//账号ID
+    uint32 roomId  = 2;//房间ID
+}
+//获取玩家数据
+message KickUserReq {
+    string uid = 1;//账号ID
+}
+message GetUserInfoRsp {
+    optional uint32 result = 1;//结果
+    repeated string money=2;
+    repeated string playerID =3;
+    repeated uint32 playerStatus=4;  // 玩家的当前状态, 0、1 表示空位无玩家,2: sitdown, 3: ready, 4: play, 5: 胜利后观战, 6: 胜利后离开,7: 组队逃跑,8: 逃跑
+
+    repeated uint32 tableID=5; // 桌子ID
+    repeated uint32 seatID=6; //座位号
+    repeated string nick=7; //昵称
+    repeated string headUrl =8; //头像
+    repeated string gender =9; //性别
+    uint32 playerNum=10;  // 玩家数量
+    repeated uint32 playerType=11;  // 玩家类型1是正常玩家2是机器人
+    optional uint32 selfSeatId=12;  // 玩家座位号
+    optional uint32 watchingPlayers=13;  // 观战玩家数量
+     optional uint32 countdown=14;  // 游戏结束倒计时
+ uint32 gameType=15;  // 游戏类型,1经典,2匹配
+}
+
+message TKickEventRsp {
+    optional uint32 PlayerNum=1; // 被踢玩家数
+    repeated KickPlayerRsp kickPlayer=2;
+}
+
+message KickPlayerRsp {
+    optional uint32 seatId=1; // 被踢玩家
+    optional uint32 planeNum=2; // 被踢飞机数
+    string planeID=3; // 飞机ID
+}
+message FinishEventRsp {
+    optional uint32 seatId=1; // 到达玩家
+    string planeId=2;// 飞机ID
+}
+message PlayerRsp {
+    optional uint32 seatId=1; // 到达玩家
+    repeated PlaneRsp planes=2;// 飞机
+}
+message PlaneRsp {
+    string planeId=1;// 飞机ID
+    optional uint32 currentIndex=2; // 飞机下标
+    optional uint32 planeStatus=3; // 0是未起飞,1是移动中,2是到达终点
+}
+message RoomDjsRsp {
+    optional uint32 time=1;// 倒计时时间    
+}
+
+//加入房间通知其他玩家
+message RoomJoinUserRsp {
+    optional uint32 result = 1;//结果
+     string money=2;
+     string playerID =3;
+     uint32 playerStatus=4;  // 玩家的当前状态, 0、1 表示空位无玩家,2: sitdown, 3: ready, 4: play, 5: 胜利后观战, 6: 胜利后离开,7: 组队逃跑,8: 逃跑
+     uint32 tableID=5; // 桌子ID
+     uint32 seatID=6; //座位号
+     string nick=7; //昵称
+     string headUrl =8; //头像
+     string gender =9; //性别
+    uint32 playerNum=10;  // 玩家数量
+    uint32 playerType=11;  // 玩家类型1是正常玩家2是机器人
+}
+
+//1,通知开始掷子并且开始倒计时
+message GameStartRsp {
+    optional uint32 result = 1;//结果
+    optional uint32 seatID = 2;//掷子玩家座位号
+    optional uint32 castSecond = 3;//结果
+}
+
+
+ //  2,客户端请求掷子,空消息
+message ThrowTheDiceReq {
+}
+//3,通知掷子结果
+message ThrowTheDiceRsp {
+    optional uint32 result = 1;//结果 0表示成功,其他表示失败
+    optional uint32 seatID = 2;//座位id
+    uint32 point = 3;//掷子点数
+    optional uint32 skipReason = 4;//玩家是否可以行棋,不为0表示不能行棋
+    optional uint32 nextTurn=5;//玩家不能行走时下一玩家
+    optional uint32 autoMove=6;//1代表正常 2自动骰子 3自动起飞,4自动行走
+    repeated PlayerRsp players=7;
+}
+//4,客户端请求起飞
+message PlaneStartReq {
+    string planeID = 1;//飞机id,从0开始
+}
+//5,通知起飞结果
+message PlaneStartRsp {
+    optional uint32 result = 1;//结果
+    optional uint32 seatID = 2;//起飞玩家座位id
+    string planeID = 3;//起飞飞机ID
+    optional uint32 nextTurn = 4;//下一个玩家座位id
+    uint32 playerNum=5;//玩家数
+    repeated PlayerRsp players=6;
+}
+  //  6,客户端请求行走
+message MoveReq {
+    string planeID = 1;//飞机id,从0开始
+}
+//7,通知移动结果
+message MoveRsp {
+    optional uint32 result = 1;//0表示成功,其他表示失败
+    optional uint32 seatID = 2;//起飞玩家座位id
+    string planeID = 3;//行走飞机ID
+    optional uint32 step = 4;//行走的步数
+    optional uint32 curPosIndex=5;// 棋子当前相对于行走路线的索引
+    optional uint32 nextTurn = 6;//下一个玩家
+    optional uint32 hasWin = 7;//玩家是否已经获胜,1表示已经获胜,0表示还没有获胜
+    uint32 playerNum=8;//玩家数
+    FinishEventRsp finishEvent=9;
+    TKickEventRsp tKickEvent=10;
+    repeated PlayerRsp players=11;
+}
+
+
+
+
+//9,客户端请求托管
+message TrusteeshipReq {
+    bool trust = 1;//true表示托管,2表示不托管
+}
+//8,通知玩家托管
+message TrusteeshipRsp {
+    bool trust = 1;//true表示托管,false表示不托管
+    optional uint32 seatID = 2;//座位id
+}
+
+
+//退出游戏请求
+message QuitReq {
+
+}
+//通知玩家退出游戏,直接剔除这个玩家
+message QuitRsp {
+    uint32 playerStatus=1;  // 玩家的当前状态, 0、1 表示空位无玩家,2: sitdown, 3: ready, 4: play, 5: 胜利后观战, 6: 胜利后离开,7: 组队逃跑,8: 逃跑 10,观战玩家
+    optional uint32 seatID=2; //座位号
+    optional uint32 nextTurn=3; //下一个座位号
+    string uid =4; //用户id
+}
+
+//通知玩家游戏结束
+message EndGameRsp {
+    repeated uint32 seatID =1; //座位号
+    repeated string playerStatus =2; //玩家状态
+    repeated uint32 kick =3; //- 玩家当局撞棋数量
+    repeated uint32 beKick =4; //- 玩家当局被撞棋数量
+    repeated uint32 money =5; //- 胜方当局赢得金额
+}
+
+//拉房失败解散游戏
+message DissolveTheGameReq {
+
+}
+
+//拉房失败解散游戏
+message DissolveTheGameRsp {
+
+}
+
+//pb解析失败
+message PbErrorRsp {
+    string messageData =1; //错误信息
+}
+
+////////////////////////////房间消息//////////////////////////////
+// 拉取房间列表 C->S, Cmd.MSGID_Get_Room_List
+message GetRoomListReq {
+}
+
+// 拉取房间列表 S->C, Cmd.MSGID_Get_Room_List
+message GetRoomListRsp {
+    uint32 result = 1;			//结果
+}
+
+
+
+
+// 踢人原因
+enum KickReason {
+    KICK_REASON_UNKNOWN = 0;
+    KICK_REASON_LOGIN_ELSEWHERE = 1;
+    KICK_REASON_HEARTBEAT_TIMEOUT = 2;
+    KICK_REASON_NOT_LOGIN = 3;
+}
+
+// 踢人通知 S->C, Cmd.MSGID_Kick_Notify
+message KickNotify {
+    uint32 reason = 1;
+}
+//退出客户端房主变更
+message RoomChangeOfHomeownerRsp {
+  string uid = 1;//玩家ID
+}
+message GetUserMoneyReq {
+  string uid = 1;//玩家ID
+}
+message GetUserMoneyRsp {
+  optional uint32 money = 1;//玩家金币
+}
+
+message DiscReq {
+  string uid = 1;//玩家ID
+    uint32 roomId  = 2;//房间ID
+}
+
+message RoomQuitReq {
+ 
+}
+
+message RoomRestartReq {
+ 
+}
+message SendMsgReq{
+    string data = 1;//消息数据
+}
+message SendMsgRsp{
+    string data = 1;//消息数据
+    string uid = 2;//消息数据
+}

+ 71 - 0
Proto/MessageID.proto

@@ -0,0 +1,71 @@
+syntax = "proto3";
+
+package BBMessage;
+option go_package = "./;message";
+
+enum MSGID
+{
+    MSGID_None  = 0;
+    MSGID_Heartbeat_Push  = 1 ;   // 心跳
+    MSGID_Login = 2 ;   // 登录
+ MSGID_Get_Room_List = 10 ;   // 拉取房间列表
+   //c-s
+    Get_User_Info_Req = 3 ;   //获取用户信息
+  //   Get_User_Info_Req2 = 31 ;   //获取用户新信息
+    Throw_The_Dice_Req = 5 ;   //客户端请求掷子,空消息
+    Start_Plane_Req = 9 ;   //客户端请求起飞
+    Move_Req = 6 ;  //客户端请求行走
+    Trusteeship_Req = 14 ;  //客户端请求托管
+    Quit_Req = 16 ;  //客户端请求退出游戏
+    Create_Game_Req = 23 ;  //客户端请求创建游戏房间
+    Join_Room_Req = 26 ;  //客户端请求加入游戏房间
+    Room_Start_Game_Req = 27 ;//客户端请求开始游戏
+   Room_Quit_Req = 33 ;  //客户端请求退出游戏房间
+  Room_Kick_User_Req = 44 ;   //客户端请求踢人
+    Room_Invite_Req = 48 ;   //客户端邀请玩家
+   Room_Info_Req = 46 ;   //客户端请求获取房间信息
+   Cancel_Match_Req = 45 ;   //客户端请求取消匹配
+      Room_Restart_Req = 51;   //客户端请求再来一局
+    Disc_Req = 54;   //客户端请求语聊房小圆盘
+    // START_GAME = 11 ;   // 拉取房间列表
+    MSGID_Kick_Notify = 1001;       // 踢人通知
+ Dissolve_The_Game_Req=56; //房主请求解散游戏
+ Close_Game_Req=58; //客户端请求关闭游戏
+Get_User_Money_Req=60; //客户端请求获取游戏金币
+
+ Send_Msg_Req=62; //客户端请求发送消息
+    //s-c
+    Get_User_Info_Rsp = 13 ;   //通知获取玩家信息
+    Join_Room_Info_Rsp = 19 ;   //通知客户端加入新玩家
+    Start_Game_Rsp = 4 ;   //通知开始游戏并且开始掷子
+    Throw_The_Dice_Rsp = 8 ;   //通知筛子结果
+    Start_Plane_Rsp = 11 ;   //通知起飞结果
+    Move_Rsp = 12 ;   //通知移动结果
+    Trusteeship_Rsp = 15 ;  //通知玩家托管结果
+    Eng_Game_Rsp = 17 ;  //通知玩家结束游戏
+    Quit_Rsq = 18 ;  //通知客户端退出游戏
+     
+    Dissolve_The_Game_Rsp=20; //20解散游戏
+    Cancel_Match_Rsp = 47 ;   //通知客户端取消匹配
+    
+    Room_Start_Game_Rsp = 21 ;   //通知客户端开始游戏
+    Room_Info_Rsp = 25 ;   //通知客户端房间玩家信息
+    Room_Join_User_Rsp = 22 ;   //通知客户端加入新玩家
+  //  Match_Join_User_Rsp = 30 ;   //通知客户端的匹配界面加入新玩家
+    Room_Kick_User_Rsp = 24 ;   //通知客户端踢人
+    Create_Game_Rsp = 28 ;  //通知客户端创建游戏房间
+    Create_Game_Error_Rsp = 34 ;  //通知客户端建房或者加入房间失败失败,当前用户已有游戏房间
+    Pb_Error_Rsp=50; //通知客户端pb解析错误
+    Move_Error_Rsp = 29 ;   //通知到客户端行走出错
+    Room_Quit_Rsp = 32 ;  //通知客户端退出游戏房间 或者解散房间
+    Room_Dissolution_Rsp = 35 ;  //通知客户端解散游戏房间
+     Room_Invite_Rsp = 49 ;  //通知客户端邀请结果
+    Match_Rsp = 52 ;  //通知客户端匹配结果
+        Room_Change_Of_Homeowner_Rsp = 53 ;  //通知客户端房主变更
+         Disc_Rsp = 55;   //通知客户端小圆盘状态
+    Room_Djs_Rsp = 57;   //通知匹配倒计时
+     Close_Game_Rsp=59; //客户端请求关闭游戏
+     Get_User_Money_Rsp=61; //客户端请求获取游戏金币
+     Send_Msg_Rsp=63; //通知客户端发送消息
+        MSGID_Heartbeat_Push_Rsp  = 64 ;   // 心跳
+}

+ 34 - 0
Server/Base/AutoInc.go

@@ -0,0 +1,34 @@
+package base
+
+type AutoInc struct {
+	start, step int
+	queue       chan int
+	running     bool
+}
+
+func NewAutoInc(start, step int) (ai *AutoInc) {
+	ai = &AutoInc{
+		start:   start,
+		step:    step,
+		running: true,
+		queue:   make(chan int, 4),
+	}
+	go ai.process()
+	return
+}
+
+func (ai *AutoInc) process() {
+	defer func() { recover() }()
+	for i := ai.start; ai.running; i = i + ai.step {
+		ai.queue <- i
+	}
+}
+
+func (ai *AutoInc) Id() int {
+	return <-ai.queue
+}
+
+func (ai *AutoInc) Close() {
+	ai.running = false
+	close(ai.queue)
+}

+ 58 - 0
Server/Base/CsvReader.go

@@ -0,0 +1,58 @@
+package base
+
+import (
+	"Server-Core/Server/Base/Log"
+	"encoding/csv"
+	"os"
+)
+
+type CsvTable struct {
+	FileName string
+	Records  []CsvRecord
+	Key      string
+}
+
+type CsvRecord struct {
+	Record map[string]string
+}
+
+func LoadCsvCfg(filename string) *CsvTable {
+	file, err := os.Open(filename)
+	if err != nil {
+		log.Error("open csv fail")
+		return nil
+	}
+	defer file.Close()
+
+	reader := csv.NewReader(file)
+	if reader == nil {
+		log.Error("NewReader return nil, file")
+		return nil
+	}
+	records, err := reader.ReadAll()
+	if err != nil {
+		log.Error("read csv fail")
+		return nil
+	}
+
+	key := ""
+	colNum := len(records[0])
+	recordNum := len(records)
+	var allRecords []CsvRecord
+	for i := 0; i < recordNum; i++ {
+		record := &CsvRecord{make(map[string]string)}
+		for k := 0; k < colNum; k++ {
+			record.Record[records[3][k]] = records[i][k]
+			if key == "" {
+				key = records[3][k]
+			}
+		}
+		allRecords = append(allRecords, *record)
+	}
+	var result = &CsvTable{
+		filename,
+		allRecords,
+		key,
+	}
+	return result
+}

+ 9 - 0
Server/Base/Interface.go

@@ -0,0 +1,9 @@
+package base
+
+type ServerExecute interface {
+	Run()
+	LogicStart()
+	LogicStep()
+	OnServerReady()
+	LogicEnd()
+}

+ 82 - 0
Server/Base/Log/LineFormatter.go

@@ -0,0 +1,82 @@
+/**
+@author: xuhanlin
+@date: 2022/6/28
+@note: 基础线性格式日志
+**/
+
+package log
+
+import (
+	"bytes"
+	"fmt"
+	"github.com/sirupsen/logrus"
+	"runtime"
+	"strconv"
+	"strings"
+)
+
+// GetGid 获取协程ID
+func GetGid() uint64 {
+	b := make([]byte, 64)
+	b = b[:runtime.Stack(b, false)]
+	b = bytes.TrimPrefix(b, []byte("goroutine "))
+	b = b[:bytes.IndexByte(b, ' ')]
+	n, err := strconv.ParseUint(string(b), 10, 64)
+	if err != nil {
+		return 0
+	}
+	return n
+}
+
+type LineFormatter struct {
+	Skip int
+}
+
+func (f *LineFormatter) Format(entry *logrus.Entry) ([]byte, error) {
+	data := ""
+	// 毫秒时间
+	data += entry.Time.Format("2006-01-02 15:04:05.000")
+	// 日志等级
+	data += "|" + strings.ToUpper(entry.Level.String())
+	// 调用信息
+	data += "|" + findCaller(f.Skip)
+	// 线程信息
+	data += "|" + strconv.FormatUint(GetGid(), 10)
+	// 日志内容
+	data += "|" + entry.Message
+	return append([]byte(data), '\n'), nil
+}
+
+func findCaller(skip int) string {
+	file, line, pc := getCaller(skip)
+	fullFnName := runtime.FuncForPC(pc)
+
+	fnName := ""
+	if fullFnName != nil {
+		fnNameStr := fullFnName.Name()
+		parts := strings.Split(fnNameStr, ".")
+		fnName = parts[len(parts)-1]
+	}
+
+	tmp := strings.Split(file, "/")
+	return fmt.Sprintf("%s:%s:%d", tmp[len(tmp)-1], fnName, line)
+}
+
+func getCaller(skip int) (string, int, uintptr) {
+	pc, file, line, ok := runtime.Caller(skip)
+	if !ok {
+		return "", 0, pc
+	}
+	n := 0
+
+	for i := len(file) - 1; i > 0; i-- {
+		if file[i] == '/' {
+			n++
+			if n >= 2 {
+				file = file[i+1:]
+				break
+			}
+		}
+	}
+	return file, line, pc
+}

+ 62 - 0
Server/Base/Log/Log.go

@@ -0,0 +1,62 @@
+package log
+
+import (
+	"github.com/sirupsen/logrus"
+	"io/ioutil"
+)
+
+type Level string
+
+const (
+	DebugLevel Level = "DEBUG"
+	InfoLevel  Level = "INFO"
+	WarnLevel  Level = "WARN"
+	ErrorLevel Level = "ERROR"
+)
+
+var logger *logrus.Logger = nil
+
+func init() {
+	logger = logrus.New()
+	logger.SetFormatter(&LineFormatter{
+		Skip: 10,
+	})
+
+	logger.SetLevel(logrus.DebugLevel)
+	return
+}
+
+// -------------------config----------------------
+
+func SetLevel(level Level) {
+	lvl, _ := logrus.ParseLevel(string(level))
+	logger.SetLevel(lvl)
+}
+
+func ConsoleOff() {
+	logger.SetOutput(ioutil.Discard)
+}
+
+func AddRotateHook(path string, day uint, pass bool) {
+	for level := logger.GetLevel(); level >= logrus.ErrorLevel; level-- {
+		logger.AddHook(NewRotateHook(level, path, day, pass))
+	}
+}
+
+// -------------------print----------------------
+
+func Debug(str string, args ...interface{}) {
+	logger.Debugf(str, args...)
+}
+
+func Info(str string, args ...interface{}) {
+	logger.Infof(str, args...)
+}
+
+func Warn(str string, args ...interface{}) {
+	logger.Warnf(str, args...)
+}
+
+func Error(str string, args ...interface{}) {
+	logger.Errorf(str, args...)
+}

+ 47 - 0
Server/Base/Log/RotateHook.go

@@ -0,0 +1,47 @@
+package log
+
+import (
+	"github.com/lestrrat-go/file-rotatelogs"
+	"github.com/rifflock/lfshook"
+	"github.com/sirupsen/logrus"
+	"time"
+)
+
+var logLevels = map[logrus.Level]string{
+	logrus.DebugLevel: "debug",
+	logrus.InfoLevel:  "info",
+	logrus.WarnLevel:  "warn",
+	logrus.ErrorLevel: "error",
+}
+
+func NewRotateHook(l logrus.Level, path string, day uint, pass bool) logrus.Hook {
+	var writerMap = lfshook.WriterMap{}
+	if path == "" {
+		path = "."
+	}
+
+	name := path + "/" + logLevels[l]
+	writer, err := rotatelogs.New(
+		name+"_%Y%m%d.log",
+		rotatelogs.WithLinkName(name+".log"),
+		rotatelogs.WithRotationTime(time.Hour*24),
+		rotatelogs.WithRotationCount(day),
+	)
+	if err != nil {
+		logrus.Errorf("config local file system for logger error: %v", err)
+	}
+
+	for level := logrus.ErrorLevel; level <= logrus.DebugLevel; level++ {
+		if level != l && (level > l || !pass) {
+			continue
+		}
+
+		writerMap[level] = writer
+	}
+
+	rotateHook := lfshook.NewHook(writerMap, &LineFormatter{
+		Skip: 13,
+	})
+
+	return rotateHook
+}

+ 103 - 0
Server/Base/Mysql.go

@@ -0,0 +1,103 @@
+package base
+
+import (
+	"Server-Core/Server/Base/Log"
+	"database/sql"
+	"fmt"
+	_ "github.com/go-sql-driver/mysql"
+	"github.com/jmoiron/sqlx"
+	"time"
+)
+
+type DBInit struct {
+	Host     string
+	Port     string
+	User     string
+	Password string
+	DBName   string
+}
+
+type Db struct {
+	sourceName string
+	conn       *sqlx.DB
+}
+
+func (db *Db) Create(init *DBInit) {
+	db.sourceName = fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?readTimeout=5s&writeTimeout=5s", init.User, init.Password, init.Host, init.Port, init.DBName)
+	db.connect()
+}
+
+func (db *Db) connect() {
+	c, err := sqlx.Open("mysql", db.sourceName)
+	if err != nil {
+		log.Error("DB连接失败 err:%s", err.Error())
+	}
+	db.conn = c
+	err = db.conn.Ping()
+	if err != nil {
+		log.Error("DB Ping Error:%s", err.Error())
+	}
+
+	db.conn.SetConnMaxLifetime(time.Minute * 3)
+	db.conn.SetMaxOpenConns(3)
+	db.conn.SetMaxIdleConns(3)
+}
+
+func (db *Db) reconnect() {
+	err := db.conn.Ping()
+	if err != nil {
+		log.Warn("DB Ping Error, Try Reconnect error:%s", err.Error())
+		db.conn.Close()
+		db.connect()
+	}
+}
+
+func (db *Db) Get(dest interface{}, query string, args ...interface{}) {
+	db.reconnect()
+	error := db.conn.Get(dest, query, args...)
+	if error != nil && error != sql.ErrNoRows {
+		log.Error("DB Get query:%s Error:%s", query, error.Error())
+	}
+}
+
+func (db *Db) Insert(query string, args ...interface{}) int64 {
+	db.reconnect()
+	result, err := db.conn.Exec(query, args...)
+	if err != nil {
+		log.Error("DB Insert query:%s Error:%s", query, err.Error())
+		return 0
+	}
+
+	id, _ := result.LastInsertId()
+	return id
+}
+
+func (db *Db) Query(query string, args ...interface{}) *sql.Rows {
+	db.reconnect()
+	rows, err := db.conn.Query(query, args...)
+	if err != nil {
+		log.Error("DB Query query:%s Error:%s", query, err.Error())
+		return nil
+	}
+	return rows
+}
+
+func (db *Db) Update(query string, args ...interface{}) {
+	db.reconnect()
+	_, err := db.conn.Exec(query, args...)
+	if err != nil {
+		log.Error("DB Query query:%s Error:%s", query, err.Error())
+	}
+}
+
+func (db *Db) Delete(query string, args ...interface{}) {
+	db.reconnect()
+	_, err := db.conn.Exec(query, args...)
+	if err != nil {
+		log.Error("DB Remove query:%s Error:%s", query, err.Error())
+	}
+}
+
+func (db *Db) Release() {
+	db.conn.Close()
+}

+ 40 - 0
Server/Base/Net.go

@@ -0,0 +1,40 @@
+package base
+
+import (
+	"Server-Core/Server/Base/Log"
+	"github.com/panjf2000/gnet"
+	"time"
+)
+
+type Net struct {
+	*gnet.EventServer
+}
+
+func (handle *Net) OnInitComplete(srv gnet.Server) (action gnet.Action) {
+	log.Info("开始监听端口 addr:%s, multi-cores:%t,loops:%d", srv.Addr.String(), srv.Multicore, srv.NumEventLoop)
+	return
+}
+
+func (handle *Net) OnShutdown(srv gnet.Server) {
+	log.Info("OnShutdown addr:%s, multi-cores:%t,loops:%d", srv.Addr.String(), srv.Multicore, srv.NumEventLoop)
+}
+
+func (handle *Net) OnOpened(c gnet.Conn) (out []byte, action gnet.Action) {
+	log.Info("OnOpened localAddr:%d, remoteAddr:%s", c.LocalAddr().String(), c.RemoteAddr().String())
+	return
+}
+
+func (handle *Net) OnClosed(c gnet.Conn, err error) (action gnet.Action) {
+	return
+}
+
+func (handle *Net) React(frame []byte, c gnet.Conn) (out []byte, action gnet.Action) {
+	return
+}
+
+func (handle *Net) PreWrite() {
+}
+
+func (handle *Net) Tick() (delay time.Duration, action gnet.Action) {
+	return
+}

+ 31 - 0
Server/Base/Random.go

@@ -0,0 +1,31 @@
+package base
+
+const F float64 = 1.0 / 0x7fff
+
+type RandGenerator struct {
+	Seed  int32
+	Count int32
+}
+
+func NewRandGenerator(seed int32) *RandGenerator {
+	return &RandGenerator{Seed: seed, Count: 0}
+}
+
+func (r *RandGenerator) RandomInt(max int) int {
+	return int(float64(max) * r.RandomFloat())
+}
+
+func (r *RandGenerator) RandomFloat() float64 {
+	r.Count++
+	r.Seed = r.Seed*214013 + 2531011
+	val := (float64((r.Seed>>16)&0x7fff) - 1) * F
+	if val > 0.99999 {
+		return 0.99999
+	} else {
+		return val
+	}
+}
+
+func (r *RandGenerator) RandomRange(min, max float64) float64 {
+	return min + r.RandomFloat()*(max-min)
+}

+ 33 - 0
Server/Base/Redis.go

@@ -0,0 +1,33 @@
+package base
+
+import (
+	"Server-Core/Server/Base/Log"
+	"context"
+	"github.com/go-redis/redis/v8"
+)
+
+type RdbInit struct {
+	Addr     string
+	DB       int
+	Password string
+}
+
+type Rdb struct {
+	client *redis.Client
+	ctx    context.Context
+}
+
+func (rdb *Rdb) Create(init *RdbInit) error {
+	rdb.client = redis.NewClient(&redis.Options{
+		Addr:     init.Addr,
+		Password: init.Password,
+		DB:       init.DB,
+	})
+
+	rdb.ctx = context.Background()
+	_, err := rdb.client.Ping(rdb.ctx).Result()
+	if err != nil {
+		log.Error("Redis Create Error:%s", err.Error())
+	}
+	return err
+}

+ 177 - 0
Server/Base/Sensitive/sensitive.go

@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2018
+ * time:   6/24/18 3:22 PM
+ * author: linhuanchao
+ * e-mail: 873085747@qq.com
+ */
+
+package Sensitive
+
+import (
+	"io/ioutil"
+	"os"
+	"strings"
+)
+
+type SensitiveMap struct {
+	sensitiveNode map[string]interface{}
+	isEnd         bool
+}
+
+var s *SensitiveMap
+
+func GetMap() *SensitiveMap {
+	if s == nil {
+		//currentPath, _  := filepath.Abs(filepath.Dir(os.Args[0]))
+		//configure       := config.GetConfig()
+		//dictionaryPath  := currentPath + configure.DictionaryPath
+		dictionaryPath := "../Config/dictionary.txt"
+		s = InitDictionary(s, dictionaryPath)
+	}
+	return s
+}
+
+/*
+初始化敏感词词典结构体
+*/
+func initSensitiveMap() *SensitiveMap {
+	return &SensitiveMap{
+		sensitiveNode: make(map[string]interface{}),
+		isEnd:         false,
+	}
+}
+
+/*
+读取词典文件
+*/
+func readDictionary(path string) []string {
+	file, err := os.Open(path)
+	if err != nil {
+		panic(err)
+	}
+	defer file.Close()
+	str, err := ioutil.ReadAll(file)
+	dictionary := strings.Fields(string(str))
+	return dictionary
+}
+
+/*
+初始化敏感词词典,根据DFA算法构建trie
+*/
+func InitDictionary(s *SensitiveMap, dictionaryPath string) *SensitiveMap {
+	s = initSensitiveMap()
+	dictionary := readDictionary(dictionaryPath)
+	for _, words := range dictionary {
+		sMapTmp := s
+		w := []rune(words)
+		wordsLength := len(w)
+		for i := 0; i < wordsLength; i++ {
+			t := string(w[i])
+			isEnd := false
+			//如果是敏感词的最后一个字,则确定状态
+			if i == (wordsLength - 1) {
+				isEnd = true
+			}
+			func(tx string) {
+				if _, ok := sMapTmp.sensitiveNode[tx]; !ok { //如果该字在该层级索引中找不到,则创建新的层级
+					sMapTemp := new(SensitiveMap)
+					sMapTemp.sensitiveNode = make(map[string]interface{})
+					sMapTemp.isEnd = isEnd
+					sMapTmp.sensitiveNode[tx] = sMapTemp
+				}
+				sMapTmp = sMapTmp.sensitiveNode[tx].(*SensitiveMap) //进入下一层级
+				sMapTmp.isEnd = isEnd
+			}(t)
+		}
+	}
+	return s
+}
+
+/*
+作用:检查是否含有敏感词,仅返回检查到的第一个敏感词
+返回值:敏感词,是否含有敏感词
+*/
+func (s *SensitiveMap) CheckSensitive(text string) (string, bool) {
+	content := []rune(text)
+	contentLength := len(content)
+	result := false
+	ta := ""
+	for index := range content {
+		sMapTmp := s
+		target := ""
+		in := index
+		for {
+			wo := string(content[in])
+			target += wo
+			if _, ok := sMapTmp.sensitiveNode[wo]; ok {
+				if sMapTmp.sensitiveNode[wo].(*SensitiveMap).isEnd {
+					result = true
+					break
+				}
+				if in == contentLength-1 {
+					break
+				}
+				sMapTmp = sMapTmp.sensitiveNode[wo].(*SensitiveMap) //进入下一层级
+				in++
+			} else {
+				break
+			}
+		}
+		if result {
+			ta = target
+			break
+		}
+	}
+	return ta, result
+}
+
+/*
+作用:返回文本中的所有敏感词
+返回值:数组,格式为“["敏感词"][敏感词在检测文本中的索引位置,敏感词长度]”
+*/
+type Target struct {
+	Indexes []int
+	Len     int
+}
+
+func (s *SensitiveMap) FindAllSensitive(text string) map[string]*Target {
+	content := []rune(text)
+	contentLength := len(content)
+	result := false
+
+	ta := make(map[string]*Target)
+	for index := range content {
+		sMapTmp := s
+		target := ""
+		in := index
+		result = false
+		for {
+			wo := string(content[in])
+			target += wo
+			if _, ok := sMapTmp.sensitiveNode[wo]; ok {
+				if sMapTmp.sensitiveNode[wo].(*SensitiveMap).isEnd {
+					result = true
+					break
+				}
+				if in == contentLength-1 {
+					break
+				}
+				sMapTmp = sMapTmp.sensitiveNode[wo].(*SensitiveMap) //进入下一层级
+				in++
+			} else {
+				break
+			}
+		}
+		if result {
+			if _, targetInTa := ta[target]; targetInTa {
+				ta[target].Indexes = append(ta[target].Indexes, index)
+			} else {
+				ta[target] = &Target{
+					Indexes: []int{index},
+					Len:     len([]rune(target)),
+				}
+			}
+		}
+	}
+	return ta
+}

+ 165 - 0
Server/Base/ServerBase.go

@@ -0,0 +1,165 @@
+package base
+
+import (
+	"Server-Core/Server/Base/Log"
+	service "Server-Core/Server/Base/Service"
+	"Server-Core/Server/Common"
+	"bufio"
+	"flag"
+	"fmt"
+	"net"
+	"os"
+	"os/signal"
+	"reflect"
+	"strconv"
+	"strings"
+	"syscall"
+	"time"
+)
+
+var Server *ServerBase
+
+type ServerBase struct {
+	running bool
+	Config  common.ServerConf
+	net     *Net
+	Timer   *Timer
+	Execute ServerExecute
+
+	kill chan os.Signal
+}
+
+// var siteMap1 map[string]string = make(map[string]string)
+
+func NewServer(execute ServerExecute) {
+	Server = new(ServerBase)
+	Server.kill = make(chan os.Signal, 1)
+	signal.Notify(Server.kill, syscall.SIGINT, syscall.SIGTERM)
+	Server.readServerConfig()
+	log.AddRotateHook(".././Log", 30, true)
+
+	log.Info("系统初始化")
+	err := service.Init()
+	if err != nil {
+		panic(err)
+	}
+	log.Info("创建服务管理 Success")
+	Server.Execute = execute
+	log.Info("============")
+	Server.start()
+}
+
+func (s *ServerBase) start() {
+	s.running = true
+
+	s.Execute.LogicStart()
+	s.Execute.OnServerReady()
+
+	for s.running {
+		select {
+		case <-time.After(16 * time.Millisecond):
+			service.Run()
+		case <-s.kill:
+			s.running = false
+			log.Info("系统开始关闭")
+		}
+	}
+
+	s.Execute.LogicEnd()
+	s.stop()
+}
+
+func (s *ServerBase) stop() {
+	service.UnInit()
+}
+
+var ip string = ""
+
+func getIp() string {
+
+	addrList, err := net.InterfaceAddrs()
+	if err != nil {
+		panic(err)
+	}
+	for _, address := range addrList {
+		if ipNet, ok := address.(*net.IPNet); ok && !ipNet.IP.IsLoopback() {
+			if ipNet.IP.To4() != nil {
+				fmt.Println(ipNet.IP.String())
+				ip = ipNet.IP.String()
+				break
+			}
+		}
+	}
+	return ip
+}
+func (s *ServerBase) readServerConfig() {
+	var tag string
+	cr := reflect.ValueOf(&s.Config).Elem()
+	flag.StringVar(&tag, "tag", "dev", "--tag=dev")
+	flag.Parse()
+	ip = getIp()
+	if ip == "192.168.1.122" {
+		file, err := os.Open(fmt.Sprintf("E://ChatGameService2/Bin/Config/%s.conf", tag))
+		if err != nil {
+			panic(err)
+		}
+		defer file.Close()
+		sc := bufio.NewScanner(file)
+		for sc.Scan() {
+			var str = sc.Text()
+			var index = strings.Index(str, "=")
+			if index == -1 {
+				continue
+			}
+			var key = strings.Trim(str[0:index], " ")
+			var value = strings.Trim(str[index+1:], " ")
+			a := cr.FieldByName(key)
+			switch a.Type().String() {
+			case "string":
+				value = strings.Trim(value, "\"")
+				a.Set(reflect.ValueOf(value))
+			case "bool":
+				b, _ := strconv.ParseBool(value)
+				a.Set(reflect.ValueOf(b))
+			case "int":
+				i, _ := strconv.Atoi(value)
+				a.Set(reflect.ValueOf(i))
+			}
+		}
+	} else {
+		//	records := base.LoadCsvCfg("E://ChatGameService2/Bin/Scp/Level.csv").Records
+		file, err := os.Open(fmt.Sprintf("../Config/%s.conf", tag))
+		if err != nil {
+			panic(err)
+		}
+		defer file.Close()
+		sc := bufio.NewScanner(file)
+		for sc.Scan() {
+			var str = sc.Text()
+			var index = strings.Index(str, "=")
+			if index == -1 {
+				continue
+			}
+			var key = strings.Trim(str[0:index], " ")
+			var value = strings.Trim(str[index+1:], " ")
+			a := cr.FieldByName(key)
+			switch a.Type().String() {
+			case "string":
+				value = strings.Trim(value, "\"")
+				a.Set(reflect.ValueOf(value))
+			case "bool":
+				b, _ := strconv.ParseBool(value)
+				a.Set(reflect.ValueOf(b))
+			case "int":
+				i, _ := strconv.Atoi(value)
+				a.Set(reflect.ValueOf(i))
+			}
+		}
+	}
+	//file, err := os.Open(fmt.Sprintf("E://ChatGameService2/Bin/Config/%s.conf", tag))
+
+}
+
+func (s *ServerBase) initTimer() {
+	s.Timer = CreateTimer()
+}

+ 25 - 0
Server/Base/Service/Def.go

@@ -0,0 +1,25 @@
+/*
+@Time : 2020/9/8 10:01
+@Author : xuhanlin
+@File : Def.go
+@Description :
+*/
+
+package service
+
+import "sync"
+
+type Msg struct {
+	Cmd  string
+	Args []interface{}
+	Sync bool
+	Done chan []interface{}
+}
+
+type Handler interface {
+	Init(ch chan Msg, wg *sync.WaitGroup, args ...interface{}) error
+	UnInit()
+	Shutdown()
+	Status() bool
+	Run()
+}

+ 113 - 0
Server/Base/Service/Service.go

@@ -0,0 +1,113 @@
+/*
+@Time : 2020/9/7 19:51
+@Author : xuhanlin
+@File : Service.go
+@Description : 服务管理器
+*/
+
+package service
+
+import (
+	log "Server-Core/Server/Base/Log"
+	"errors"
+	"sync"
+)
+
+var m *mgr
+
+type context struct {
+	name string
+	args []interface{}
+	ch   chan Msg
+	h    Handler
+}
+
+type mgr struct {
+	serviceByName map[string]*context
+	wg            sync.WaitGroup
+}
+
+func Init() error {
+	m = new(mgr)
+	m.serviceByName = make(map[string]*context)
+	return nil
+}
+
+func UnInit() {
+	for _, v := range m.serviceByName {
+		v.h.UnInit()
+		close(v.ch)
+	}
+
+	m.wg.Wait()
+	m.serviceByName = make(map[string]*context)
+}
+
+func Run() {
+	for _, v := range m.serviceByName {
+		if v.h.Status() == false {
+			log.Warn("重启服务 name:%s", v.name)
+			v.h.Init(v.ch, &m.wg, v.args...)
+			go v.h.Run()
+			m.wg.Add(1)
+		}
+	}
+}
+
+func Register(name string, h Handler, args ...interface{}) error {
+	_, ok := m.serviceByName[name]
+	if ok {
+		return errors.New("服务已注册: " + name)
+	}
+
+	c := new(context)
+	c.name = name
+	c.ch = make(chan Msg, 1000)
+	c.h = h
+	c.args = args
+	err := h.Init(c.ch, &m.wg, c.args...)
+	if err != nil {
+		return err
+	}
+	go h.Run()
+	m.serviceByName[name] = c
+	m.wg.Add(1)
+	return nil
+}
+
+func Send(name string, cmd string, args ...interface{}) {
+	c, ok := m.serviceByName[name]
+	if !ok {
+		log.Warn("服务未注册name:%s", c.name)
+	}
+
+	var msg Msg
+	msg.Cmd = cmd
+	msg.Args = args
+	c.ch <- msg
+	if len(c.ch) > int(float64(cap(c.ch))*0.8) {
+		log.Warn("服务负载过高name:%s,total:%d,cur:%d")
+	}
+}
+
+func Call(name string, cmd string, args ...interface{}) ([]interface{}, error) {
+	c, ok := m.serviceByName[name]
+	if !ok {
+		return []interface{}{}, errors.New("服务未注册: " + name)
+	}
+
+	done := make(chan []interface{})
+	var msg Msg
+	msg.Cmd = cmd
+	msg.Args = args
+	msg.Sync = true
+	msg.Done = done
+	c.ch <- msg
+	if len(c.ch) > int(float64(cap(c.ch))*0.8) {
+		log.Warn("服务负载过高name:%s,total:%d,cur:%d")
+	}
+
+	ret := <-done
+	close(msg.Done)
+	return ret, nil
+}

+ 24 - 0
Server/Base/SpinLock.go

@@ -0,0 +1,24 @@
+package base
+
+import (
+	"runtime"
+	"sync"
+	"sync/atomic"
+)
+
+type spinLock uint32
+
+func (sl *spinLock) Lock() {
+	for !atomic.CompareAndSwapUint32((*uint32)(sl), 0, 1) {
+		runtime.Gosched()
+	}
+}
+
+func (sl *spinLock) Unlock() {
+	atomic.StoreUint32((*uint32)(sl), 0)
+}
+
+func NewSpinLock() sync.Locker {
+	var lock spinLock
+	return &lock
+}

+ 40 - 0
Server/Base/TcpCodec.go

@@ -0,0 +1,40 @@
+package base
+
+import (
+	"bytes"
+	"encoding/binary"
+	"github.com/panjf2000/gnet"
+	log "github.com/sirupsen/logrus"
+)
+
+type TcpCodec struct {
+}
+
+func (pc *TcpCodec) Encode(c gnet.Conn, buf []byte) (out []byte, err error) {
+	rs := make([]byte, 4)
+	binary.LittleEndian.PutUint32(rs, uint32(len(buf)))
+	out = bytes.Join([][]byte{rs, buf}, []byte(""))
+	return
+}
+
+func (pc *TcpCodec) Decode(c gnet.Conn) (out []byte, err error) {
+
+	log.Info("收到了消息", c.Read())
+
+	//	c.AsyncWrite(out)
+	//读取前四个字节 size int, buf []byte
+	rs, bs := c.ReadN(4)
+	if rs != 4 {
+		return
+	}
+	//
+	ts := int(binary.LittleEndian.Uint32(bs)) + rs
+	size, buf := c.ReadN(ts)
+	if size != ts {
+		return
+	}
+
+	c.ShiftN(size)
+	out = buf[4:]
+	return
+}

+ 176 - 0
Server/Base/Timer.go

@@ -0,0 +1,176 @@
+package base
+
+import (
+	"Server-Core/Server/Base/Log"
+	"sync"
+	"time"
+)
+
+const (
+	TimerNearShift  = 8
+	TimerNear       = 1 << TimerNearShift
+	TimerNearMask   = TimerNear - 1
+	TimerLevelShift = 6
+	TimerLevel      = 1 << TimerLevelShift
+	TimerLevelMask  = TimerLevel - 1
+)
+
+type Timer struct {
+	near      [TimerNear]linkList
+	t         [4][TimerLevel]linkList
+	lock      sync.Locker
+	time      uint32
+	startTime uint32
+	current   uint64
+}
+
+type timerNode struct {
+	next   *timerNode
+	expire uint32
+	f      func([]interface{})
+	argv   []interface{}
+}
+
+type linkList struct {
+	head timerNode
+	tail *timerNode
+}
+
+func CreateTimer() (timer *Timer) {
+	timer = new(Timer)
+
+	timer.lock = NewSpinLock()
+
+	for i := range timer.near {
+		linkClear(&timer.near[i])
+	}
+
+	for i := range timer.t {
+		for j := range timer.t[i] {
+			linkClear(&timer.t[i][j])
+		}
+	}
+
+	timer.startTime, timer.current = sysTime()
+
+	return
+}
+
+func (timer *Timer) Run() {
+	_, cs := sysTime()
+	if cs < timer.current {
+		log.Error("time diff error from:%d", timer.current)
+	} else {
+		diff := cs - timer.current
+		timer.current += diff
+		for i := 0; i < int(diff); i++ {
+			timer.update()
+		}
+	}
+}
+
+func (timer *Timer) Add(time int, f func([]interface{}), argv ...interface{}) {
+	node := new(timerNode)
+	timer.lock.Lock()
+	defer timer.lock.Unlock()
+
+	node.expire = uint32(time) + timer.time
+	node.f = f
+	node.argv = argv
+	timer.addNode(node)
+}
+
+func (timer *Timer) update() {
+	timer.lock.Lock()
+	defer timer.lock.Unlock()
+
+	timer.execute()
+	timer.shift()
+	timer.execute()
+}
+
+func (timer *Timer) execute() {
+	idx := timer.time & TimerNearMask
+
+	for timer.near[idx].head.next != nil {
+		node := linkClear(&timer.near[idx])
+		timer.lock.Unlock()
+		dispatch(node)
+		timer.lock.Lock()
+	}
+}
+
+func (timer *Timer) shift() {
+	mask := uint32(TimerNear)
+	timer.time++
+	ct := timer.time
+	if ct == 0 {
+		timer.moveList(3, 0)
+	} else {
+		time := ct >> TimerNearShift
+		for i := 0; (ct & (mask - 1)) == 0; i++ {
+			idx := time & TimerLevelMask
+			if idx != 0 {
+				timer.moveList(i, idx)
+				break
+			}
+			mask <<= TimerLevelShift
+			time >>= TimerLevelShift
+		}
+	}
+}
+
+func (timer *Timer) moveList(level int, idx uint32) {
+	current := linkClear(&timer.t[level][idx])
+	for current != nil {
+		next := current.next
+		timer.addNode(current)
+		current = next
+	}
+}
+
+func (timer *Timer) addNode(node *timerNode) {
+	time := node.expire
+	currentTime := timer.time
+
+	if (time | TimerNearMask) == (currentTime | TimerNearMask) {
+		link(&timer.near[time&TimerNearMask], node)
+	} else {
+		var i int
+		var mask uint32 = TimerNear << TimerLevelShift
+		for i = 0; i < 3; i++ {
+			if (time | (mask - 1)) == (currentTime | (mask - 1)) {
+				break
+			}
+			mask <<= TimerLevelShift
+		}
+		link(&timer.t[i][((time>>(TimerNearShift+i*TimerLevelShift))&TimerLevelMask)], node)
+	}
+}
+
+func sysTime() (sec uint32, cs uint64) {
+	t := time.Now()
+	sec = uint32(t.Unix())
+	cs = uint64(t.UnixNano() / 10000000)
+	return
+}
+
+func linkClear(list *linkList) (node *timerNode) {
+	node = list.head.next
+	list.head.next = nil
+	list.tail = &list.head
+	return
+}
+
+func link(list *linkList, node *timerNode) {
+	list.tail.next = node
+	list.tail = node
+	node.next = nil
+}
+
+func dispatch(node *timerNode) {
+	for node != nil {
+		node.f(node.argv)
+		node = node.next
+	}
+}

+ 108 - 0
Server/Base/Util.go

@@ -0,0 +1,108 @@
+package base
+
+import (
+	log "Server-Core/Server/Base/Log"
+	"bytes"
+	"runtime"
+	"strconv"
+	"strings"
+	"time"
+)
+
+// 字符串首字母转大写
+func StrFirstToUpper(str string) string {
+	if len(str) < 1 {
+		return ""
+	}
+	strArray := []rune(str)
+	if strArray[0] >= 97 && strArray[0] <= 122 {
+		strArray[0] -= 32
+	}
+	return string(strArray)
+}
+
+// 两个时间戳是否同一天
+func IsSameDay(time1, time2 int64, offset int) bool {
+	return StartTimestamp(time1, offset) == StartTimestamp(time2, offset)
+}
+
+// 获取今天0点时间戳(计算时差)
+func TodayStartTimestamp(offset int) int64 {
+	return StartTimestamp(time.Now().Unix(), offset)
+}
+
+// 获取指定时间戳的0点时间戳(计算时差)
+func StartTimestamp(timestamp int64, offset int) int64 {
+	timeStr := time.Unix(timestamp, 0).Format("2006-01-02")
+	t, _ := time.Parse("2006-01-02", timeStr)
+	t2 := t.Unix() + int64(offset)
+	if t2 > timestamp {
+		t2 -= 86400
+	}
+	return t2
+}
+
+// unicode转中文
+func Unicode2Hans(raw []byte) []byte {
+	str, err := strconv.Unquote(strings.Replace(strconv.Quote(string(raw)), `\\u`, `\u`, -1))
+	if err != nil {
+		return raw
+	}
+	return []byte(str)
+}
+
+// 打印Panic堆栈信息
+func PanicTrace(kb int) string {
+	s := []byte("/src/runtime/panic.go")
+	e := []byte("\ngoroutine ")
+	line := []byte("\n")
+	stack := make([]byte, kb<<10) //4KB
+	length := runtime.Stack(stack, true)
+	start := bytes.Index(stack, s)
+	stack = stack[start:length]
+	start = bytes.Index(stack, line) + 1
+	stack = stack[start:]
+	end := bytes.LastIndex(stack, line)
+	if end != -1 {
+		stack = stack[:end]
+	}
+	end = bytes.Index(stack, e)
+	if end != -1 {
+		stack = stack[:end]
+	}
+	stack = bytes.TrimRight(stack, "\n")
+	return string(stack)
+}
+
+// 通用异常捕获
+func TryE() {
+	errs := recover()
+	if errs == nil {
+		return
+	}
+
+	log.Error("%v\n", errs)
+	log.Error(panicTrace(8))
+}
+
+func panicTrace(kb int) string {
+	s := []byte("/src/runtime/panic.go")
+	e := []byte("\ngoroutine ")
+	line := []byte("\n")
+	stack := make([]byte, kb<<10) //4KB
+	length := runtime.Stack(stack, true)
+	start := bytes.Index(stack, s)
+	stack = stack[start:length]
+	start = bytes.Index(stack, line) + 1
+	stack = stack[start:]
+	end := bytes.LastIndex(stack, line)
+	if end != -1 {
+		stack = stack[:end]
+	}
+	end = bytes.Index(stack, e)
+	if end != -1 {
+		stack = stack[:end]
+	}
+	stack = bytes.TrimRight(stack, "\n")
+	return string(stack)
+}

+ 39 - 0
Server/Base/WebCodec.go

@@ -0,0 +1,39 @@
+package base
+
+import (
+	"bytes"
+	"encoding/binary"
+	"github.com/panjf2000/gnet"
+	log "github.com/sirupsen/logrus"
+)
+
+type WebTcpCodec struct {
+}
+
+func (pc *TcpCodec) WebEncode(c gnet.Conn, buf []byte) (out []byte, err error) {
+	rs := make([]byte, 4)
+	binary.LittleEndian.PutUint32(rs, uint32(len(buf)))
+	out = bytes.Join([][]byte{rs, buf}, []byte(""))
+	return
+}
+
+func (pc *TcpCodec) WebDecode(c gnet.Conn) (out []byte, err error) {
+
+	log.Info("收到了消息", c.Read())
+
+	//	c.AsyncWrite(out)
+	rs, bs := c.ReadN(4)
+	if rs != 4 {
+		return
+	}
+
+	ts := int(binary.LittleEndian.Uint32(bs)) + rs
+	size, buf := c.ReadN(ts)
+	if size != ts {
+		return
+	}
+
+	c.ShiftN(size)
+	out = buf[4:]
+	return
+}

+ 23 - 0
Server/Common/GlobalDef.go

@@ -0,0 +1,23 @@
+package common
+
+type Message struct {
+	F    func(int, []byte)
+	Id   int
+	Data []byte
+}
+
+type ServerConf struct {
+	GameName   string
+	ServerName string
+	Debug      bool
+	ClientPort int
+	DBHost     string
+	DBPort     string
+	DBUser     string
+	DBPassword string
+	DBName     string
+	LogLevel   string
+	GMPort     int
+	WEBPort    string
+	BaseURL    string
+}

+ 14 - 0
Server/Config/dev.conf

@@ -0,0 +1,14 @@
+GameName = "bbb"
+ServerName = "game_forest"
+Debug = true
+ClientPort = 48000
+LogLevel = "debug"
+WEBPort = ":8090"
+DBHost = "114.132.71.177"
+DBPort = "3306"
+DBUser = "test"
+DBPassword = "P_test865952!sdwcx"
+DBName = "chat_game"
+
+GMPort = 46001
+BaseURL="http://47.242.46.203/"

Datei-Diff unterdrückt, da er zu groß ist
+ 0 - 0
Server/Config/dictionary.txt


+ 14 - 0
Server/Config/test.conf

@@ -0,0 +1,14 @@
+GameName = "bbb"
+ServerName = "game_forest"
+Debug = true
+ClientPort = 48000
+LogLevel = "debug"
+WEBPort = ":8089"
+DBHost = "114.132.71.177"
+DBPort = "3306"
+DBUser = "test"
+DBPassword = "P_test865952!sdwcx"
+DBName = "chat_game"
+
+GMPort = 46001
+BaseURL="https://api.raingo.net/"

BIN
Server/GameServer/GameServer


BIN
Server/GameServer/Main


+ 11 - 0
Server/GameServer/Main.go

@@ -0,0 +1,11 @@
+package main
+
+import (
+	base "Server-Core/Server/Base"
+	"Server-Core/Server/GameServer/Server"
+)
+
+func main() {
+	gameServer := new(server.GameServer)
+	base.NewServer(gameServer)
+}

+ 22 - 0
Server/GameServer/Server/DB/DBDef.go

@@ -0,0 +1,22 @@
+package db
+
+import (
+	"Server-Core/Server/Base"
+)
+
+var mysql *base.Db
+
+type Account struct {
+	PlayerId      int64  `db:"playerId"`
+	Uid           string `db:"uid"`
+	PassWd        string `db:"passWd"`
+	Name          string `db:"nickName"`
+	CreateDate    string `db:"createDate"`
+	UpdateDate    string `db:"updateDate"`
+	LastLoginTime int64  `db:"lastLoginTime"`
+}
+
+func Create(init *base.DBInit) {
+	mysql = new(base.Db)
+	mysql.Create(init)
+}

+ 32 - 0
Server/GameServer/Server/DB/DBOperation.go

@@ -0,0 +1,32 @@
+package db
+
+import (
+	"time"
+)
+
+// 通过账号ID查询玩家是否存在
+func UidIsExit(uid string) bool {
+	rows := mysql.Query("select * from Account where uid=? ", 1)
+	if rows == nil { //不存在
+		return false
+	}
+
+	defer rows.Close()
+	if rows.Next() == false {
+		return false
+	}
+	return true
+}
+
+// Account
+func QueryPlayerByUid(account *Account, uid string) {
+	mysql.Get(account, "select * from Account  where uid = ?", uid)
+}
+
+func InsertNewPlayer(uid, passWd string) int64 {
+	return mysql.Insert("replace into Account(uid,passWd,createDate,updateDate,lastLoginTime) values(?,?,?,?,?)", uid, passWd, time.Now(), time.Now(), time.Now().Unix())
+}
+
+func UpdatePlayer(playerId int64) {
+	mysql.Update("update Account set updateDate=?, lastLoginTime=? where playerId=?", time.Now(), 0, playerId)
+}

+ 130 - 0
Server/GameServer/Server/Logic/Execute.go

@@ -0,0 +1,130 @@
+/*
+@Time : 2020/9/8 19:37
+@Author : xuhanlin
+@File : Execute.go
+@Description :
+*/
+
+package logic
+
+import (
+	log "Server-Core/Server/Base/Log"
+	service "Server-Core/Server/Base/Service"
+	db "Server-Core/Server/GameServer/Server/DB"
+	message "Server-Core/Server/Message"
+	"github.com/golang/protobuf/proto"
+
+	//"strconv"
+	"time"
+)
+
+var execute map[string]func([]interface{}) []interface{}
+var clientCmd map[message.MSGID]func(int, []byte)
+
+func register() {
+	execute = make(map[string]func([]interface{}) []interface{})
+	execute["GMOnHandle"] = GMOnHandle
+	//业务逻辑
+	clientCmd = make(map[message.MSGID]func(int, []byte))
+	clientCmd[message.MSGID_MSGID_Heartbeat_Push] = HeartBeatReq
+	clientCmd[message.MSGID_MSGID_Login] = LoginReq
+	//获取用户信息
+	//clientCmd[message.MSGID_MSGID_User_Info] = GetUserInfo
+	//clientCmd[message.MSGID_Throw_The_Dice] = ThrowTheDice
+	//clientCmd[message.MSGID_Move] = Move
+}
+
+func HeartBeatReq(clientId int, data []byte) {
+	player := G.playerMng.GetPlayerByClientId(clientId)
+	if player != nil {
+		player.LastHeartbeat = time.Now().Unix()
+	}
+}
+
+// 登录流程,只是个模版
+func LoginReq(clientId int, data []byte) {
+	log.Info("rece====LoginReq")
+	req := &message.LoginReq{}
+	rsp := &message.LoginRsp{}
+	rsp.Result = uint32(message.GameStatus_GAME_STATUS_OK)
+	var player *Player = nil
+	for {
+		err := proto.Unmarshal(data, req) //解包
+		if err != nil {
+			log.Error("Unmarshal fail clientId:%d err:%s", clientId, err.Error())
+			rsp.Result = uint32(message.GameStatus_GAME_STATUS_PB_ERR)
+			break
+		}
+		//测试期间:没有账号则创建账号和密码,有账号则验证密码
+		log.Info("LoginReq recive clientId:%d Req={%s}", clientId, req)
+		//先验证账号和密码不能为空
+		if len(req.Uid) == 0 || len(req.PassWd) == 0 {
+			log.Error("clientId:%d Login err uid:%s passwd:%s", clientId, req.Uid, req.PassWd)
+			rsp.Result = uint32(message.GameStatus_GAME_STATUS_UID_PASSWD_NIL)
+			break
+		}
+
+		account := db.Account{}
+		db.QueryPlayerByUid(&account, req.Uid) //查询玩家是否存在能确定唯一RoleId
+		playerId := account.PlayerId
+		//验证账号
+		if playerId != 0 && req.PassWd != account.PassWd {
+			log.Error("Login passwd error clientId:%d account.PassWd:%s req.PassWd:%s", clientId, account.PassWd, req.PassWd)
+			rsp.Result = uint32(message.GameStatus_GAME_STATUS_PASSWD_ERROR)
+			break
+		}
+		player = G.playerMng.GetPlayerByPlayerId(playerId) //玩家缓存不再则new一个新玩家,如果存在则顶号
+		if player != nil {
+			G.playerMng.KickOld(player, clientId) //顶号
+		} else {
+			player, err = G.playerMng.NewPlayer(req.Uid, req.PassWd, clientId, &account) //new一个新玩家放到内存中
+			if err != nil {
+				log.Error("Login NewPlayer clientId:%d  error:%s", clientId, err.Error())
+				rsp.Result = uint32(message.GameStatus_GAME_STATUS_INNER_ERR)
+				break
+			}
+		}
+		player.AfterLoad()
+
+		player.FillLoginRsp(rsp)
+		break
+	}
+	//登录的回包打印,客户端提到登录回包,有时候玩家ID为0
+	log.Info("login send clientId:%d Uid:%s rsp:%s", clientId, req.Uid, rsp)
+	rData, ok := proto.Marshal(rsp) //回包
+	if ok == nil {
+		if player != nil {
+			player.SendMsg(message.MSGID_MSGID_Login, rData)
+		} else {
+			//可能密码错误,没获取到玩家指针也要发送错误码的
+			SendMsgByClientId(clientId, message.MSGID_MSGID_Login, rData)
+		}
+	}
+}
+
+// 查询房间列表
+func GetRoomList(clientId int, data []byte) {
+	rsp := &message.GetRoomListRsp{}
+
+	var player *Player = nil
+	for {
+		player = G.playerMng.GetPlayerByClientId(clientId) //通过客户端链接找到玩家是否存在?
+		if player == nil {
+			log.Error("GetRoomList player nil clientId:%d", clientId)
+			service.Send("clientMgr", "kick", clientId, message.KickReason_KICK_REASON_NOT_LOGIN)
+			break
+		}
+		log.Info("GetRoomList recive PlayerId:%d GetRoomListReq", player.PlayerId)
+
+		break
+	}
+
+	if player != nil {
+		rsp = G.roomMng.GetRoomList() //
+		log.Info("send GetRoomList PlayerId:%d rsp::%s", player.PlayerId, rsp)
+		rData, ok := proto.Marshal(rsp) //回包
+		if ok == nil {
+			player.SendMsg(message.MSGID_MSGID_Get_Room_List, rData)
+		}
+	}
+}

+ 62 - 0
Server/GameServer/Server/Logic/Gm.go

@@ -0,0 +1,62 @@
+package logic
+
+import (
+	log "Server-Core/Server/Base/Log"
+	"encoding/json"
+)
+
+type GMOnStatus struct {
+}
+
+// GM消息类型
+const (
+	GM_TYPE_SERVER_STATUS int = 1 //服务器玩家在线状态 GMOnStatus
+)
+
+type GMBody struct {
+	ErrorCode int64       `json:"errorCode"`
+	ErrorMsg  string      `json:"errorMsg"`
+	Data      interface{} `json:"data"`
+}
+
+// 其他服务调用
+func GMOnHandle(args []interface{}) []interface{} {
+	cmd := args[0].(int)
+	msg_body := args[1].(string)
+	var body GMBody
+	switch cmd {
+	case GM_TYPE_SERVER_STATUS: //服务器玩家在线状态
+		body = OnStatus(msg_body)
+		break
+	default:
+		body.ErrorCode = GM_ERROR_FAIL
+		body.ErrorMsg = "没有这个消息号"
+		break
+	}
+	return []interface{}{body}
+}
+
+// GM错误码类型
+const (
+	GM_ERROR_SUCESS      int64 = 0     //成功
+	GM_ERROR_FAIL        int64 = 20027 //失败
+	GM_ERROR_ANALY_ERROE int64 = 20028 //结构体解析错误
+)
+
+// 在线状态
+func OnStatus(msg_body string) GMBody {
+	var req GMOnStatus
+	err := json.Unmarshal([]byte(msg_body), &req)
+	var rsp GMBody
+	if err != nil {
+		rsp.ErrorCode = GM_ERROR_ANALY_ERROE
+		rsp.ErrorMsg = "结构体解析错误"
+		return rsp
+	}
+	log.Info("Received onStatus:%v", req)
+	playerNum := len(G.playerMng.playerByClientId)
+	playerNum = 10
+	log.Info("playerNum:%d", playerNum)
+	rsp.Data = playerNum
+	return rsp
+}

+ 113 - 0
Server/GameServer/Server/Logic/LogicMgr.go

@@ -0,0 +1,113 @@
+package logic
+
+import (
+	base "Server-Core/Server/Base"
+	log "Server-Core/Server/Base/Log"
+	service "Server-Core/Server/Base/Service"
+	message "Server-Core/Server/Message"
+	"sync"
+	"time"
+)
+
+var G *LogicMgr
+
+type LogicMgr struct {
+	running bool
+	ch      chan service.Msg
+	wg      *sync.WaitGroup
+
+	roomMng   *RoomMgr
+	playerMng *PlayerMgr
+
+	beginTick      int64 //服务器开启时间
+	LastStatusTick int64 //上一次记录服务器状态的时间
+}
+
+func (mgr *LogicMgr) Init(ch chan service.Msg, wg *sync.WaitGroup, args ...interface{}) error {
+	register()
+	mgr.running = true
+	mgr.ch = ch
+	mgr.wg = wg
+
+	mgr.roomMng = CreateRoomMgr()
+	mgr.playerMng = CreatePlayerMgr()
+	mgr.beginTick = time.Now().Unix()
+	mgr.LastStatusTick = 0
+
+	G = mgr
+
+	return nil
+}
+
+func (mgr *LogicMgr) UnInit() {
+	mgr.running = false
+}
+
+func (mgr *LogicMgr) Status() bool {
+	return mgr.running
+}
+
+func (mgr *LogicMgr) Shutdown() {
+	log.Info("logicMgr服务退出")
+	mgr.running = false
+	mgr.wg.Done()
+}
+
+func (mgr *LogicMgr) Run() {
+	defer base.TryE()
+	defer mgr.Shutdown()
+
+	timer := time.After(time.Millisecond * 500) // timer
+	for mgr.running {
+		select {
+		case <-timer:
+			timer = time.After(time.Millisecond * 500) // timer
+			mgr.roomMng.Run()                          //遍历房间
+			now := time.Now().Unix()
+			for _, player := range mgr.playerMng.playerByClientId {
+				if now-player.LastHeartbeat > 30 {
+					service.Send("clientMgr", "kick", player.ClientId, message.KickReason_KICK_REASON_HEARTBEAT_TIMEOUT)
+					mgr.playerMng.RemovePlayer(player.PlayerId)
+					//mgr.roomMng.RemovePlayer(player.PlayerId)
+				} else {
+					player.Run()
+				}
+			}
+			//每过半个小时打印一次服务器上玩家和房间的总人数
+			if now-mgr.LastStatusTick >= 1800 {
+				log.Info("服务器人数:%d  房间数量:%d", len(mgr.playerMng.playerByClientId), len(mgr.roomMng.roomByRoomId))
+				mgr.LastStatusTick = now
+			}
+
+		case msg, ok := <-mgr.ch:
+			if !ok {
+				continue
+			}
+			ok = true
+			cmd := msg.Cmd
+			if msg.Cmd == "clientCmd" {
+				msgId := msg.Args[0].(int)
+				cmd = string(msgId)
+				handler, ok := clientCmd[message.MSGID(msgId)]
+				if ok {
+					handler(msg.Args[1].(int), msg.Args[2].([]byte))
+				}
+			} else {
+				handler, ok := execute[msg.Cmd]
+				if !ok {
+					log.Error("未注册命令 cmd:%s", msg.Cmd)
+					continue
+				}
+				if msg.Sync {
+					msg.Done <- handler(msg.Args)
+				} else {
+					handler(msg.Args)
+				}
+			}
+			if !ok {
+				log.Error("未注册命令 cmd:%s", cmd)
+				continue
+			}
+		}
+	}
+}

+ 69 - 0
Server/GameServer/Server/Logic/Player.go

@@ -0,0 +1,69 @@
+package logic
+
+import (
+	service "Server-Core/Server/Base/Service"
+	"Server-Core/Server/GameServer/Server/DB"
+	"Server-Core/Server/Message"
+	"time"
+)
+
+type Player struct {
+	PlayerId      int64
+	Name          string
+	ClientId      int
+	Uid           string
+	LastLoginTime int64
+	LastHeartbeat int64
+}
+
+var badNetworkThreshold int64 = 15
+
+func CreatePlayer() *Player {
+	player := new(Player)
+	return player
+}
+
+func (p *Player) Run() {
+}
+
+func (p *Player) Init() {
+	p.LastHeartbeat = time.Now().Unix()
+}
+
+func (p *Player) Load() {
+	p.LastHeartbeat = time.Now().Unix()
+
+}
+
+// 是否处于弱网状态?
+func (p *Player) IsWeakNetwork() bool {
+	//15s没收到心跳包,表示处于弱网状态
+	if time.Now().Unix()-p.LastHeartbeat >= badNetworkThreshold {
+		return true
+	}
+	return false
+}
+
+func (p *Player) AfterLoad() {
+	db.UpdatePlayer(p.PlayerId)
+}
+
+// 填充登录回包数据
+func (p *Player) FillLoginRsp(rsp *message.LoginRsp) {
+	playerId := p.PlayerId
+	rsp.PlayerId = playerId
+	//填充登录回包
+}
+
+func (p *Player) LoadOther() {
+	p.LastHeartbeat = time.Now().Unix()
+
+}
+
+func SendMsgByClientId(clientId int, cmd message.MSGID, data []byte) {
+	service.Send("clientMgr", "sendMsgById", clientId, cmd, data)
+}
+
+func (p *Player) SendMsg(cmd message.MSGID, data []byte) {
+	service.Send("clientMgr", "sendMsgById", p.ClientId, cmd, data)
+}

+ 80 - 0
Server/GameServer/Server/Logic/PlayerMgr.go

@@ -0,0 +1,80 @@
+package logic
+
+import (
+	service "Server-Core/Server/Base/Service"
+	"Server-Core/Server/GameServer/Server/DB"
+	message "Server-Core/Server/Message"
+	"time"
+)
+
+type PlayerMgr struct {
+	playerByClientId map[int]*Player
+	playerByPlayerId map[int64]*Player
+	playerByUid      map[string]*Player
+}
+
+func CreatePlayerMgr() *PlayerMgr {
+	mgr := new(PlayerMgr)
+	mgr.playerByClientId = make(map[int]*Player)
+	mgr.playerByPlayerId = make(map[int64]*Player)
+	mgr.playerByUid = make(map[string]*Player)
+
+	return mgr
+}
+
+func (mgr *PlayerMgr) Run() {
+}
+
+func (mgr *PlayerMgr) GetPlayerByClientId(clientId int) *Player {
+	return mgr.playerByClientId[clientId]
+}
+
+func (mgr *PlayerMgr) GetPlayerByPlayerId(playerId int64) *Player {
+	return mgr.playerByPlayerId[playerId]
+}
+
+func (mgr *PlayerMgr) GetPlayerByUid(uid string) *Player {
+	return mgr.playerByUid[uid]
+}
+
+func (mgr *PlayerMgr) RemovePlayer(playerId int64) {
+	player, ok := mgr.playerByPlayerId[playerId]
+	if ok {
+		delete(mgr.playerByClientId, player.ClientId)
+		delete(mgr.playerByUid, player.Uid)
+		delete(mgr.playerByPlayerId, player.PlayerId)
+	}
+}
+
+func (mgr *PlayerMgr) NewPlayer(uid, passWd string, clientId int, account *db.Account) (*Player, error) {
+	player := CreatePlayer()
+	//如果该玩家为新号则入库,如果不是新号则加载玩家数据
+	playerId := account.PlayerId
+	if playerId == 0 {
+		player.PlayerId = db.InsertNewPlayer(uid, passWd)
+		player.LastLoginTime = 0
+		player.ClientId = clientId
+		player.Uid = uid
+		player.Init()
+	} else {
+		player.PlayerId = playerId
+		player.Name = account.Name
+		player.LastLoginTime = account.LastLoginTime
+		player.ClientId = clientId
+		player.Uid = account.Uid
+		player.Load()
+	}
+
+	mgr.playerByClientId[player.ClientId] = player
+	mgr.playerByPlayerId[player.PlayerId] = player
+	mgr.playerByUid[player.Uid] = player
+	return player, nil
+}
+
+func (mgr *PlayerMgr) KickOld(player *Player, newClientId int) {
+	delete(mgr.playerByClientId, player.ClientId)
+	service.Send("clientMgr", "kick", player.ClientId, message.KickReason_KICK_REASON_LOGIN_ELSEWHERE)
+	player.ClientId = newClientId
+	player.LastHeartbeat = time.Now().Unix()
+	mgr.playerByClientId[newClientId] = player
+}

+ 32 - 0
Server/GameServer/Server/Logic/Room.go

@@ -0,0 +1,32 @@
+package logic
+
+type PlayerInfo struct {
+	playerId     int64
+	name         string
+	isFinishLoad bool
+	teamId       int64  //队伍ID,其实就是准备房间的ID,用来区分队友
+	index        uint32 //玩家序号,从开始
+}
+
+type Room struct {
+	roomId         int64                 //房间ID
+	roomPlayerInfo map[int64]*PlayerInfo //房间玩家信息
+	roomMasterId   int64                 //房间归属者ID
+	status         int                   //房间状态
+	roomType       int                   //房间类型
+	startGameTick  int64                 //开始游戏的时间戳,20s没有加载完则直接进入游戏
+	mateTick       int64                 //匹配时间,超时则重新回到房间
+
+	tick      int64 //战斗开启后过去的秒数
+	creatTime int64 //创建房间时间
+}
+
+var times int64 = 0
+
+func (room *Room) Run() {
+
+}
+
+func (room *Room) Init() {
+
+}

+ 96 - 0
Server/GameServer/Server/Logic/RoomMgr.go

@@ -0,0 +1,96 @@
+package logic
+
+import (
+	log "Server-Core/Server/Base/Log"
+	message "Server-Core/Server/Message"
+)
+
+const (
+	roomIdMin int64 = 10000 //房间ID下限
+	roomIdMax int64 = 99999 //房间ID上限
+)
+
+type RoomMgr struct {
+	roomByRoomId     map[int64]*Room //房间列表
+	roomIdByPlayerId map[int64]int64 //玩家ID到房间ID的一个映射
+
+	idGenList map[int64]int64 //策划需求房间ID范围为10000-99999,则直接遍历一遍把ID占位分配好,反正也不可能一次性开十万个房间
+}
+
+func CreateRoomMgr() *RoomMgr {
+	mgr := new(RoomMgr)
+	mgr.roomByRoomId = make(map[int64]*Room)
+	mgr.roomIdByPlayerId = make(map[int64]int64)
+	mgr.idGenList = make(map[int64]int64)
+	for i := roomIdMin; i <= roomIdMax; i++ {
+		mgr.idGenList[i] = 0 //初始化,全部没有被占用
+	}
+	return mgr
+}
+
+// 获取一个未被占用的房间ID
+func (mgr *RoomMgr) GetID() int64 {
+	for id, status := range mgr.idGenList {
+		if status == 0 {
+			return id
+		}
+	}
+	log.Error("GetID error ID is 0")
+	return 0 //ID全部被用完了则返回0,一般不会这样会
+}
+
+// 设置一个ID为已使用状态
+func (mgr *RoomMgr) SetIdUsed(id int64) {
+	mgr.idGenList[id] = 1
+}
+
+// 设置一个ID为未使用状态
+func (mgr *RoomMgr) SetIdUnUsed(id int64) {
+	mgr.idGenList[id] = 0
+}
+
+// 通过房间ID获取房间对象
+func (mgr *RoomMgr) GetRoomByRoomId(roomId int64) *Room {
+	return mgr.roomByRoomId[roomId]
+}
+
+// 通过玩家ID获取房间ID
+func (mgr *RoomMgr) GetRoomIdByPlayerId(playerId int64) int64 {
+	return mgr.roomIdByPlayerId[playerId]
+}
+
+// 移除玩家到房间的映射
+func (mgr *RoomMgr) RemovePlayerIdFromRoom(playerId int64) {
+	delete(mgr.roomIdByPlayerId, playerId)
+}
+
+// 通过玩家ID获取准备房间对象
+func (mgr *RoomMgr) GetRoomByPlayerId(PlayerId int64) *Room {
+	roomId := mgr.GetRoomIdByPlayerId(PlayerId)
+	room := mgr.GetRoomByRoomId(roomId)
+	return room
+}
+
+func (mgr *RoomMgr) Run() {
+	//遍历房间的帧同步消息
+	for _, room := range mgr.roomByRoomId {
+		//房间人数为0或者房间状态为结束状态则释放该房间
+		if len(room.roomPlayerInfo) == 0 || room.status == 2 {
+			delete(mgr.roomByRoomId, room.roomId)
+			mgr.SetIdUnUsed(room.roomId)
+			//释放房间做个打印
+			continue
+		}
+		room.Run() //跑帧同步逻辑
+	}
+}
+
+// 拉取所有准备房间的数据
+func (mgr *RoomMgr) GetRoomList() *message.GetRoomListRsp {
+	roomListRsp := &message.GetRoomListRsp{}
+	for _, room := range mgr.roomByRoomId {
+		log.Info("GetRoomList any Room:{%s}", room.roomId)
+	}
+
+	return roomListRsp
+}

+ 231 - 0
Server/GameServer/Server/PlaneGame/GmWeb/Http.go

@@ -0,0 +1,231 @@
+package GmWeb
+
+import (
+	"Server-Core/Server/GameServer/Server/PlaneGame/Module"
+	"sync"
+
+	//"Server-Core/Server/GameServer/Server/PlaneGame/Module"
+	message "Server-Core/Server/Message"
+	"encoding/binary"
+
+	"net/http"
+
+	"github.com/gin-gonic/gin"
+	"github.com/golang/protobuf/proto"
+	"github.com/gorilla/websocket"
+	log "github.com/sirupsen/logrus"
+)
+
+func Cors() gin.HandlerFunc {
+	return func(context *gin.Context) {
+		//log.Info("收到请求")
+		method := context.Request.Method
+		context.Header("Access-Control-Allow-Origin", "*")
+		context.Header("Access-Control-Allow-Headers", "Content-Type, Content-Length, Authorization, Accept, X-Requested-With , yourHeaderFeild,access-control-allow-headers,access-control-allow-methods,access-control-allow-origin")
+		context.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT,PATCH, HEAD")
+		context.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Content-Type")
+		context.Header("Access-Control-Allow-Credentials", "true")
+
+		// 允许放行OPTIONS请求
+		if method == "OPTIONS" {
+			context.AbortWithStatus(http.StatusNoContent)
+		}
+		//log.Info("context====", context)
+		context.Next()
+		/*context.Writer.Header().Set("Access-Control-Allow-Origin", "*")
+		context.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
+		context.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type,AccessToken,X-CSRF-Token, Authorization, Token")
+		context.Writer.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
+		context.Writer.Header().Set("Access-Control-Max-Age", "172800")
+		context.Writer.Header().Set("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Content-Type")
+		context.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
+		context.Next()*/
+
+	}
+}
+func Webinit(port string) {
+
+	// mp := make(map[string]any, 2)
+	// err = yaml.Unmarshal(dataBytes, mp)
+
+	//gin.SetMode(gin.ReleaseMode)
+	router := gin.Default()
+	router.Use(Cors())
+	router.POST("/dev/game/start", gameInit)
+	router.GET("/dev/game/configReload", gameConfigReload)
+	router.GET("/ping", ping)
+	router.GET("/dev/game/getRoomPage", GetRoomPage)
+	router.GET("/dev/game/getToken", Gettoken)
+	router.GET("/dev/room/init", RoomInit)
+	router.Run(port)
+}
+func GetRoomPage(c *gin.Context) {
+
+	sql := Module.GetRoomPage(c)
+	log.Print("接收到了===login1", sql)
+	c.JSON(http.StatusOK, sql)
+}
+
+ func RoomInit(c *gin.Context) {
+
+ 	sql := Module.RoomInit2(c)
+// 	//log.Print("接收到了===login1", sql)
+ 	c.JSON(http.StatusOK, sql)
+ }
+func Gettoken(c *gin.Context) {
+
+	sql := Module.Gettoken(c)
+	log.Print("接收到了===login1", sql)
+	c.JSON(http.StatusOK, sql)
+}
+
+func gameInit(c *gin.Context) {
+
+	sql := Module.GameInit(c)
+	log.Print("接收到了===login1", sql)
+	c.JSON(http.StatusOK, sql)
+}
+func gameConfigReload(c *gin.Context) {
+
+	Module.ReloadConfig(c)
+	var sql = Module.SqlResponse{
+		Code:    200,
+		Message: "成功",
+	}
+	c.JSON(http.StatusOK, sql)
+}
+
+var upGrader = websocket.Upgrader{
+	CheckOrigin: func(r *http.Request) bool {
+		return true
+	},
+}
+
+var CmdExector map[int16]func(ws *websocket.Conn, data []byte) = make(map[int16]func(ws *websocket.Conn, data []byte))
+var lock sync.Mutex
+
+func ping(c *gin.Context) {
+
+	// 升级get请求为webSocket协议
+	ws, err := upGrader.Upgrade(c.Writer, c.Request, nil)
+	
+	log.Info("连接成功")
+	//upGrader.Upgrade(c.Writer, c.Request, nil);
+
+	if err != nil {
+		return
+	}
+	defer ws.Close() //返回前关闭
+	for {
+		// 读取ws中的数据
+
+		mt2, message2, err := ws.ReadMessage()
+		if err != nil {
+		//	println("err========",err.Error())
+			//log.Info("收到了断开通知")
+			//log.Printf("错误")
+			//log.Info("错误", err)
+			//log.Printf("有玩家退出1")
+			player := Module.GamePlayers[Module.ClientUserIds[ws]]
+			//log.Printf("有玩家退出", player)
+			if nil != player {
+				if websocket.IsCloseError(err, websocket.CloseNormalClosure, websocket.CloseGoingAway) {
+					
+					lock.Lock()
+					if player.Status != 0 {
+						Module.QuitRoom(player, ws, 0)
+					}
+
+					lock.Unlock()
+				} else {
+					lock.Lock()
+
+					if player.Status != 0 {
+						Module.QuitRoom(player, ws, 0)
+					}
+					lock.Unlock()
+				}
+			}
+
+			//CloseNormalClosure           = 1000
+			// CloseGoingAway               = 1001
+			// CloseProtocolError           = 1002
+			// CloseUnsupportedData         = 1003
+			// CloseNoStatusReceived        = 1005
+			// CloseAbnormalClosure         = 1006
+			// CloseInvalidFramePayloadData = 1007
+			// ClosePolicyViolation         = 1008
+			// CloseMessageTooBig           = 1009
+			// CloseMandatoryExtension      = 1010
+			// CloseInternalServerErr       = 1011
+			// CloseServiceRestart          = 1012
+			// CloseTryAgainLater           = 1013
+			// CloseTLSHandshake            = 1015
+
+			/*else {
+				// 连接异常关闭
+				fmt.Println("连接异常关闭:", err)
+			}*/
+			//wsMap.delete();
+			//break
+		}
+		//pkg_length, gateway_type, protocol_type, UID, protoBytes := unpkgData(message2) //解包
+		if mt2 == websocket.BinaryMessage {
+			//注册到map,统一解析错误
+			_, protocol_type, protoBytes := unpkgData2(message2) //解包
+			log.Info("msgId===", protocol_type)
+			CmdExector[int16(protocol_type)](ws, protoBytes)
+
+		}
+	}
+}
+
+// 解密
+func byteDencrypt(byteData []byte, len int) int32 {
+	//测试位 []byte{48,191,8,0}
+	//4-1-0  = 3  byteData[3] = 0
+	//4-1-1  = 2  byteData[2] = 8
+	//4-1-2  = 1  byteData[1] = 191
+	//4-1-3  = 0  byteData[0] = 48
+	//取最后一位
+	x := int32(byteData[len-1])
+	//len-1为第一个数没有进行位移,所以去掉循环
+	for i := 0; i < len-1; i++ {
+		index := len - 1 - i                //反向取数
+		x = x<<8 + int32(byteData[index-1]) //保存上次计算结果
+		//fmt.Println(x,i,index)
+	}
+	//fmt.Println(x)
+	return x
+}
+
+// 解析客户端发来的数据包
+// 返回参数: int32:长度 int32:主协议 int32:消息协议 int32:UID  []byte:proto二进制数据
+func unpkgData(data []byte) (int32, int32, int32, int32, []byte) {
+	pkg_length := byteDencrypt([]byte{data[0], data[1]}, 2)
+	gateway_type := byteDencrypt([]byte{data[2], data[3]}, 2)
+	protocol_type := byteDencrypt([]byte{data[4], data[5]}, 2)
+	UID := byteDencrypt([]byte{data[6], data[7], data[8], data[9]}, 4)
+	protoBytes := make([]byte, pkg_length-10)
+	for i, _ := range protoBytes {
+		protoBytes[i] = data[i+10]
+	}
+	return pkg_length, gateway_type, protocol_type, UID, protoBytes
+}
+
+// 解析客户端发来的数据包
+// 返回参数: int32:长度 int32:主协议 int32:消息协议 int32:UID  []byte:proto二进制数据
+func unpkgData2(data []byte) (uint32, uint16, []byte) {
+	u := binary.BigEndian.Uint32(data[:4])
+	datapkg2 := make([]byte, 2)
+	datapkg2[0] = data[4]
+	datapkg2[1] = data[5]
+	u2 := binary.BigEndian.Uint16(datapkg2)
+	protoBytes := make([]byte, len(data)-6)
+	for i, _ := range protoBytes {
+		protoBytes[i] = data[i+6]
+	}
+	req := &message.LoginReq{}
+	proto.Unmarshal(protoBytes, req) //解包
+	return u, u2, protoBytes
+}

+ 55 - 0
Server/GameServer/Server/PlaneGame/GmWeb/Mgr.go

@@ -0,0 +1,55 @@
+package GmWeb
+
+import (
+	log "Server-Core/Server/Base/Log"
+	service "Server-Core/Server/Base/Service"
+	"encoding/json"
+	"io/ioutil"
+	"net/http"
+	"strconv"
+)
+
+type Payload struct {
+	Msg_id   int    `json:"msg_id"`
+	Msg_body string `json:"msg_body"`
+}
+
+func Create(port int) {
+	http.HandleFunc("/gmApi/cmd", func(w http.ResponseWriter, r *http.Request) {
+		// 设置CORS头
+		w.Header().Set("Access-Control-Allow-Origin", "*")
+		w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
+
+		if r.Method != http.MethodPost {
+			http.Error(w, "Invalid request method", http.StatusMethodNotAllowed)
+			return
+		}
+
+		body, err := ioutil.ReadAll(r.Body)
+		if err != nil {
+			http.Error(w, "Error reading request body", http.StatusInternalServerError)
+			return
+		}
+		var payload Payload
+		err = json.Unmarshal(body, &payload)
+		if err != nil {
+			http.Error(w, "Error unmarshalling JSON", http.StatusInternalServerError)
+			return
+		}
+		log.Info("http analy struct message:%v", payload)
+
+		ret, err := service.Call("logicMgr", "GMOnHandle", payload.Msg_id, payload.Msg_body)
+		if err != nil {
+			log.Error(err.Error(), nil)
+			return
+		}
+
+		log.Info("http send message:%s", ret[0])
+		w.Header().Set("Content-Type", "application/json")
+		json.NewEncoder(w).Encode(ret[0]) // 作为示例,我们将接收到的payload返回给客户端
+	})
+
+	log.Info("Starting GMWeb server at port:%d", port)
+	go http.ListenAndServe(":"+strconv.Itoa(port), nil)
+
+}

+ 120 - 0
Server/GameServer/Server/PlaneGame/GmWeb/Sw.go

@@ -0,0 +1,120 @@
+package GmWeb
+
+import (
+	"encoding/json"
+	"errors"
+	"fmt"
+	rtctokenbuilder "github.com/AgoraIO/Tools/DynamicKey/AgoraDynamicKey/go/src/rtctokenbuilder2"
+	"log"
+	"net/http"
+	"strconv"
+)
+
+type rtc_int_token_struct struct {
+	Uid_rtc_int  uint32 `json:"uid"`
+	Channel_name string `json:"ChannelName"`
+	Role         uint32 `json:"role"`
+}
+
+var rtc_token string
+var int_uid uint32
+var channel_name string
+
+var role_num uint32
+var role rtctokenbuilder.Role
+
+// 使用 RtcTokenBuilder 来生成 RTC Token
+func generateRtcToken(int_uid uint32, channelName string, role rtctokenbuilder.Role) {
+
+	appID := "53c2ddc63bbc41228d916e1bea9a566a"
+	appCertificate := "ccefdf8d574d42a6a042a9415fceb18c"
+	// AccessToken2 过期的时间,单位为秒
+	// 当 AccessToken2 过期但权限未过期时,用户仍在频道里并且可以发流,不会触发 SDK 回调。
+	// 但一旦用户和频道断开连接,用户将无法使用该 Token 加入同一频道。请确保 AccessToken2 的过期时间晚于权限过期时间。
+	tokenExpireTimeInSeconds := uint32(180)
+	// 权限过期的时间,单位为秒。
+	// 权限过期30秒前会触发 token-privilege-will-expire 回调。
+	// 权限过期时会触发 token-privilege-did-expire 回调。
+	// 为作演示,在此将过期时间设为 40 秒。你可以看到客户端自动更新 Token 的过程
+	privilegeExpireTimeInSeconds := uint32(180)
+
+	result, err := rtctokenbuilder.BuildTokenWithUid(appID, appCertificate, channelName, int_uid, role, tokenExpireTimeInSeconds, privilegeExpireTimeInSeconds)
+	if err != nil {
+		fmt.Println(err)
+	} else {
+		fmt.Printf("Token with uid: %s\n", result)
+		fmt.Printf("uid is %d\n", int_uid)
+		fmt.Printf("ChannelName is %s\n", channelName)
+		fmt.Printf("Role is %d\n", role)
+	}
+	rtc_token = result
+}
+
+func rtcTokenHandler(w http.ResponseWriter, r *http.Request) {
+	w.Header().Set("Content-Type", "application/json; charset=UTF-8")
+	w.Header().Set("Access-Control-Allow-Origin", "*")
+	w.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS")
+	w.Header().Set("Access-Control-Allow-Headers", "*")
+
+	if r.Method == "OPTIONS" {
+		w.WriteHeader(http.StatusOK)
+		return
+	}
+
+	if r.Method != "POST" && r.Method != "OPTIONS" {
+		http.Error(w, "Unsupported method. Please check.", http.StatusNotFound)
+		return
+	}
+
+	var t_int rtc_int_token_struct
+	var unmarshalErr *json.UnmarshalTypeError
+	int_decoder := json.NewDecoder(r.Body)
+	int_err := int_decoder.Decode(&t_int)
+	if int_err == nil {
+
+		int_uid = t_int.Uid_rtc_int
+		channel_name = t_int.Channel_name
+		role_num = t_int.Role
+		switch role_num {
+		case 1:
+			role = rtctokenbuilder.RolePublisher
+		case 2:
+			role = rtctokenbuilder.RoleSubscriber
+		}
+	}
+	if int_err != nil {
+
+		if errors.As(int_err, &unmarshalErr) {
+			errorResponse(w, "Bad request. Wrong type provided for field "+unmarshalErr.Value+unmarshalErr.Field+unmarshalErr.Struct, http.StatusBadRequest)
+		} else {
+			errorResponse(w, "Bad request.", http.StatusBadRequest)
+		}
+		return
+	}
+
+	generateRtcToken(int_uid, channel_name, role)
+	errorResponse(w, rtc_token, http.StatusOK)
+	log.Println(w, r)
+}
+
+func errorResponse(w http.ResponseWriter, message string, httpStatusCode int) {
+	w.Header().Set("Content-Type", "application/json")
+	w.Header().Set("Access-Control-Allow-Origin", "*")
+	w.WriteHeader(httpStatusCode)
+	resp := make(map[string]string)
+	resp["token"] = message
+	resp["code"] = strconv.Itoa(httpStatusCode)
+	jsonResp, _ := json.Marshal(resp)
+	w.Write(jsonResp)
+
+}
+
+func InitSw() {
+	// 使用 int 型 uid 生成 RTC Token
+	http.HandleFunc("/fetch_rtc_token", rtcTokenHandler)
+	fmt.Printf("Starting server at port 8091\n")
+	//fb平台要注释掉,语聊房要开启
+	// if err := http.ListenAndServe(":8091", nil); err != nil {
+	// 	log.Fatal(err)
+	// }
+}

+ 34 - 0
Server/GameServer/Server/PlaneGame/Module/Db.go

@@ -0,0 +1,34 @@
+package Module
+
+import (
+	"fmt"
+
+	_ "github.com/go-sql-driver/mysql"
+
+	"xorm.io/xorm"
+	"xorm.io/xorm/names"
+)
+
+var Engine *xorm.Engine
+
+func init() {
+	var err2 error
+	Engine, err2 = xorm.NewEngine("mysql", "root:psGCMSfy9Vds@tcp(8.141.80.205:3306)/chat_game?charset=utf8")
+	//maxIdleCount 最大空闲连接数,默认不配置,是2个最大空闲连接
+	Engine.SetMaxIdleConns(20)
+	//最大连接数,默认不配置,是不限制最大连接数
+	Engine.SetMaxOpenConns(100)
+	//maxLifetime 连接最大存活时间
+	Engine.SetConnMaxLifetime(1000)
+	
+	if err2 != nil {
+		fmt.Println("连接数据库失败", err2)
+		return
+	}
+	// 会在控制台打印执行的sql
+
+	//	XormDb.SetColumnMapper(core.SnakeMapper{})
+	Engine.SetTableMapper(names.SnakeMapper{})
+	Engine.SetColumnMapper(names.SnakeMapper{})
+	Engine.ShowSQL(true)
+}

+ 1655 - 0
Server/GameServer/Server/PlaneGame/Module/Plane.go

@@ -0,0 +1,1655 @@
+package Module
+
+import (
+	log "Server-Core/Server/Base/Log"
+	"Server-Core/Server/GameServer/Server/PlaneGame/Utils"
+	message "Server-Core/Server/Message"
+	scheme "Server-Core/Server/Scheme"
+	"fmt"
+	"math/rand"
+	"strconv"
+	"time"
+
+	"github.com/golang/protobuf/proto"
+	"github.com/gorilla/websocket"
+)
+
+// 结构体  id ,值 根据值查询id,再根据id 查询对应的关联数据
+// 用户 -》房间 -》 所有用户-》所有座位-》飞机
+//
+
+// 1一个房间对应多个玩家,一个玩家对应多个飞机 ,初始化生成房间号
+// 游戏初始化根据http请求初始化
+
+func broadInfoSz(player *GamePlayer) {
+	//先启动倒计时防止
+	log.Info("开启倒计时等待下一位玩家摇筛子,先开始倒计时,防止不能停止倒计时", player.SeatId)
+	ticker := time.NewTicker(time.Second * 1)
+	player.GameRoom.ticker = ticker
+	go countdonw(player, 1, "")
+	errcode2 := uint32(message.GameStatus_GAME_STATUS_OK)
+	seatID := player.SeatId
+	//返回房间id
+	time2 := uint32(10)
+	rsp3 := &message.GameStartRsp{SeatID: &seatID, CastSecond: &time2, Result: &errcode2}
+	//log.Info("通知开始掷子,并开启倒计时", *rsp3.SeatID)
+	rData3, _ := proto.Marshal(rsp3) //回包
+
+	BroadInfo(player.GameRoom, int16(message.MSGID_Start_Game_Rsp), rData3)
+
+}
+
+func countdonw(player *GamePlayer, Type int, planeId string) {
+	//type 1是摇筛子,而是起飞,3是行走
+
+	defer player.GameRoom.ticker.Stop()
+	for i := 0; i < 11; i++ {
+		if player != nil {
+			if player.GameRoom != nil {
+				if player.GameRoom.ticker != nil {
+					select {
+					case <-player.GameRoom.ticker.C:
+						//超过10秒没执行就会进入托管,
+						if i == 10 {
+							//超时了开始托管
+
+							log.Info("operate time out update status 9", player.Uid)
+							rsp2 := &message.TrusteeshipRsp{}
+							rsp2.SeatID = &player.SeatId
+							player.Status = uint32(message.GameStatus_Player_Status_9)
+							rsp2.Trust = true
+							rData, _ := proto.Marshal(rsp2) //回包
+							BroadInfo(player.GameRoom, int16(message.MSGID_Trusteeship_Rsp), rData)
+							player.GameRoom.ticker.Stop()
+							if player.GameRoom.GameEnd == GamePlaying {
+								fmt.Println("自动摇筛子", i)
+								if 1 == Type {
+									go ThrowTheDice2(player.Uid)
+								} else if 2 == Type {
+									//起飞
+									go StartFly2(player.Uid, planeId)
+								} else if 3 == Type {
+									//行走
+									go Move2(player.Uid, planeId)
+								}
+
+							}
+							fmt.Println("托管结束", i)
+							return
+						}
+						fmt.Println("托管倒计时", i, player.SeatId)
+					}
+				}
+			}
+		}
+
+	}
+}
+
+// 拉房倒计时
+func countdonw2(player *GamePlayer, num int) {
+	ticker := time.NewTicker(time.Second * 1)
+	player.GameRoom.ticker = ticker
+	defer ticker.Stop()
+	for i := 0; i < 61; i++ {
+		select {
+		case <-ticker.C:
+			//room.TimeOut=room.TimeOut-1
+			//超过10秒没执行就会进入托管,
+			if i == 60 {
+				//超时了需要告诉客户端解散游戏,发起http请求给语聊房回滚数据
+				log.Warn("开始游戏一直没进入游戏数据回退")
+				Dissolve_The_Game(player)
+				ticker.Stop()
+				return
+			}
+			fmt.Println("进房倒计时", i, num)
+
+		}
+	}
+}
+
+// 匹配倒计时
+func countdonw3(uid string, roomId uint32) {
+	ticker := time.NewTicker(time.Second * 1)
+
+	var player = GamePlayers[uid]
+	player.GameRoom.ticker = ticker
+	defer player.GameRoom.ticker.Stop()
+	for i := 0; i < 31; i++ {
+		if player != nil {
+			if player.GameRoom != nil {
+				if player.GameRoom.ticker != nil {
+					select {
+					case <-ticker.C:
+						//room.TimeOut=room.TimeOut-1
+						//超过10秒没执行就会进入托管,
+
+						if i == 30 {
+							player.GameRoom.ticker.Stop()
+							if len(player.GameRoom.Players) > 1 {
+								player.GameRoom.ticker.Stop()
+								for _, player := range player.GameRoom.Players {
+									for j := 0; j < len(MatchGameplayers); j++ {
+										if player.Uid == MatchGameplayers[j].Uid {
+											//MatchGameplayers[i].Status = uint32(message.GameStatus_Player_Status_2)
+											MatchGameplayers = append(MatchGameplayers[:j], MatchGameplayers[j+1:]...)
+										}
+									}
+
+								}
+								player.GameRoom.StartPlayerNum = len(player.GameRoom.Players)
+								time.Sleep(1 * time.Second)
+								rsp3 := &message.RoomStartGameRsp{}
+								rData3, _ := proto.Marshal(rsp3) //回包
+								log.Info("广播开始玩游戏")
+								go countdonw2(player, 2)
+								BroadInfo(player.GameRoom, int16(message.MSGID_Room_Start_Game_Rsp), rData3)
+								// result := Utils.ChatRoomBroadcast(player.GameRoom.ChatRoomId, BroadcastInvisit, player.GameRoom.Id)
+								// if result.Code != 200 {
+								// 	log.Info("通知语聊房开始游戏失败")
+								// }
+
+							} else {
+
+								CancenMatch(player.Uid)
+								//Dissolve_The_Game(player)
+							}
+
+							//player.GameRoom.ch2 = nil
+							//	wg.Done()
+
+							return
+						} else {
+							//通知到玩家倒计时
+							rsp3 := &message.RoomDjsRsp{}
+							var time = uint32(i)
+							rsp3.Time = &time
+							rData, _ := proto.Marshal(rsp3) //回包
+							BroadInfoRoom(player.GameRoom, int16(message.MSGID_Room_Djs_Rsp), rData)
+							fmt.Println("匹配倒计时", i)
+						}
+
+					}
+				}
+			}
+		}
+
+	}
+}
+
+// 游戏结算倒计时退出
+func countdonw4(player *GamePlayer, num int) {
+	ticker := time.NewTicker(time.Second * 1)
+	player.GameRoom.ticker = ticker
+	///player.GameRoom
+	defer ticker.Stop()
+	for i := 0; i < 10; i++ {
+		select {
+		case <-ticker.C:
+			//room.TimeOut=room.TimeOut-1
+			//超过10秒没执行就会进入托管,
+			if i == 60 {
+				//超时了需要告诉客户端解散游戏,发起http请求给语聊房回滚数据
+				//log.Warn("开始游戏一直没进入游戏数据回退")
+				//Dissolve_The_Game(player)
+				ticker.Stop()
+				return
+			}
+			fmt.Println("结算倒计时", i, num)
+
+		}
+	}
+}
+
+// 前六轮过后(第七轮),没有可起飞飞机,必出6, 开始摇骰子
+// 根据权重扔骰子  要记录该玩家每一轮出的值
+// 房间数对应多个玩家,每个玩家对应一个游戏轮数,每个游戏轮数对应多个玩家的掷筛记录
+
+func ThrowTheDice(ws *websocket.Conn, data []byte) {
+	uid := ClientUserIds[ws]
+	player := getPlayer(uid)
+	if player.Status == 9 {
+		BroadErrorMsg("托管状态下,不能执行操作", ws)
+		return
+	}
+	ThrowTheDice2(uid)
+}
+
+func ThrowTheDice2(uid string) {
+
+	/*defer func() {
+		//捕获test抛出的panic
+		if err := recover(); err != nil {
+			fmt.Println("协程发生错误", err)
+			log.Warn("开始游戏一直没进入游戏数据回退")
+		}
+	}()*/
+	player := getPlayer(uid)
+	if player==nil{
+		log.Warn("该玩家已退出")
+		return
+	}
+	//room := userRoom[player.Uid]
+	room := player.GameRoom
+	if room.GameEnd == GameEnd {
+		log.Warn("游戏已经结束")
+		return
+	}
+	if room.ticker != nil {
+		log.Info("停止倒计时")
+		room.ticker.Stop()
+	} else {
+		log.Info("计时器为空")
+	}
+
+	rand.Seed(time.Now().UnixNano())
+	num := rand.Int31n(10000)
+	var ds uint32 = 0
+	//判断是否是最后一个棋子
+	planes := player.GamePlane
+	var distance3 = 56
+	var range1 = []*scheme.SzItem{}
+	if player.FinishNum == 3 {
+		//获取最后跑的飞机是否在终点区
+		//获取飞机距离重点区的距离
+		//var isFinish = 0
+		for i := 0; i < len(planes); i++ {
+			if planes[i].IsFly == 1 {
+				distance3 = 56 - int(planes[i].CurPosIndex)
+				//log.Info("更新距离", distance3)
+				break
+			}
+		}
+		if distance3 <= 6 {
+			//log.Info("查询range4<6")
+			range1 = GetRange4(1, 1, 6, room.DataList)
+		} else {
+			//最后一架飞机 玩家人数小于4,不在终点区 ,
+			if len(room.Players) < 4 {
+				//log.Info("查询range2<4")
+				range1 = GetRange2(1, 2, 1, room.DataList)
+			} else {
+				//最后一架飞机 ,玩家人数等于4,,不在终点区 ,
+				//log.Info("查询range2=4")
+				range1 = GetRange2(1, 1, 1, room.DataList)
+			}
+		}
+	} else {
+		//	var range1 = []*scheme.SzItem{}
+		if len(room.Players) < 4 {
+			//不是最后一架飞机,玩家人数小于4
+			//log.Info("查询range<4", room.DataList)
+			range1 = GetRange(2, 2, room.DataList)
+		} else {
+			//不是最后一架飞机,玩家人数等于4
+			//log.Info("查询range=", room.DataList)
+			range1 = GetRange(2, 1, room.DataList)
+		}
+	}
+	//log.Info("range========", range1)
+	if num < range1[0].Weight {
+		ds = uint32(range1[0].Ds)
+	} else if num < range1[1].Weight {
+		ds = uint32(range1[1].Ds)
+	} else if num < range1[2].Weight {
+		ds = uint32(range1[2].Ds)
+	} else if num < range1[3].Weight {
+		ds = uint32(range1[3].Ds)
+	} else if num < range1[4].Weight {
+		ds = uint32(range1[4].Ds)
+	} else if num < range1[5].Weight {
+		ds = uint32(range1[5].Ds)
+	}
+	// 玩家没有棋子可操作时 若前六轮没有一个六,则第7轮必出6
+	var ismove = 1
+	for i := 0; i < len(planes); i++ {
+		if planes[i].IsFly == 1 {
+			ismove = 2
+			break
+		}
+	}
+	gamenum := player.Num
+	if ismove == 1 {
+		//0,1,2,3,4,5,6
+		if gamenum > 4 {
+			//最后一次是6 ,
+			log.Warn("没有飞机起飞的情况下,进入了第七轮")
+			var issix = 0
+			for i := gamenum - 5; i < gamenum; i++ {
+				if len(player.NumberOfRounds[i].NumberOfRounds) > 1 {
+					log.Warn("上一次", *player.NumberOfRounds[i].NumberOfRounds[0])
+					issix = 1
+					break
+				}
+			}
+			if issix == 0 {
+				ds = 6
+			}
+		}
+	}
+
+	//如果当前轮里没有数据则直接添加,如果已有数据,则看是不是6 是的话加在当前轮,不是的话,新加一轮
+	if len(player.NumberOfRounds[gamenum].NumberOfRounds) == 0 {
+		player.NumberOfRounds[gamenum].NumberOfRounds = append(player.NumberOfRounds[gamenum].NumberOfRounds, &ds)
+	} else {
+		//如果是第一轮,多次投色子
+		i := player.NumberOfRounds[gamenum].NumberOfRounds[len(player.NumberOfRounds[gamenum].NumberOfRounds)-1]
+		if *i == 6 {
+			//上一次是6的情况下直接追加当前轮,
+			player.NumberOfRounds[gamenum].NumberOfRounds = append(player.NumberOfRounds[gamenum].NumberOfRounds, &ds)
+		} else {
+			////上一轮不是是6的情况下添加新的轮数
+			var rounds = []*uint32{}
+			rounds = append(rounds, &ds)
+			player.Num = player.Num + 1
+			var gameRound2 *GameNumberOfRounds = new(GameNumberOfRounds)
+			(*gameRound2).Num = player.Num
+			(*gameRound2).NumberOfRounds = rounds
+			player.NumberOfRounds = append(player.NumberOfRounds, gameRound2)
+
+		}
+	}
+	//玩家都准备完毕了就可以游戏
+	rsp := &message.ThrowTheDiceRsp{}
+	errcode2 := uint32(message.GameStatus_GAME_STATUS_OK)
+	rsp.Result = &errcode2
+	rsp.Point = ds
+	//如果没有飞机起飞,并且点数不为6则跳过当局
+	//players := userRoom[player.Uid].Players
+	//planes := player.GamePlane
+	var canMove = 0
+	var flyplane []*GamePlane
+	var unflyplane []*GamePlane
+	//var moveplane *GamePlane
+	for i := 0; i < len(planes); i++ {
+		//正在移动加点数距离不到终点或者没有起飞点数为6 可以操作
+		if planes[i].IsFly == 1 {
+
+			//isFly = 1
+			if planes[i].CurPosIndex+ds <= 56 {
+				flyplane = append(flyplane, planes[i])
+				canMove = canMove + 1
+				//	moveplane=planes[i]
+			}
+			//break
+		} else if planes[i].IsFly == 0 {
+
+			if ds == 6 {
+				unflyplane = append(unflyplane, player.GamePlane[i])
+				canMove = canMove + 1
+				//	moveplane=planes[i]
+			}
+		}
+	}
+
+	if canMove > 0 {
+		if ds != 6 {
+			setNextTurn(true, player, rsp)
+		} else {
+			//判断是不是3次连续6
+			log.Info("这是第几轮", gamenum)
+			if len(player.NumberOfRounds[gamenum].NumberOfRounds) > 2 {
+				u := player.NumberOfRounds[gamenum].NumberOfRounds[len(player.NumberOfRounds[gamenum].NumberOfRounds)-1]
+				u2 := player.NumberOfRounds[gamenum].NumberOfRounds[len(player.NumberOfRounds[gamenum].NumberOfRounds)-2]
+				u3 := player.NumberOfRounds[gamenum].NumberOfRounds[len(player.NumberOfRounds[gamenum].NumberOfRounds)-3]
+				log.Warn("第一回合%d", *u)
+				log.Warn("第二回合%d", *u2)
+				log.Warn("第三回合%d", *u3)
+				if *u == 6 && *u2 == 6 && *u3 == 6 {
+					//log.Info("飞机已起飞,点数为6的情况下,连续三次6", nextSeatId)  三次六的情况下直接结束这一轮
+					setNextTurn(false, player, rsp)
+					var rounds = []*uint32{}
+					//rounds = append(rounds, &ds)
+					player.Num = player.Num + 1
+					var gameRound2 *GameNumberOfRounds = new(GameNumberOfRounds)
+					(*gameRound2).Num = player.Num
+					(*gameRound2).NumberOfRounds = rounds
+					player.NumberOfRounds = append(player.NumberOfRounds, gameRound2)
+
+				} else {
+
+					setNextTurn(true, player, rsp)
+				}
+
+			} else {
+				//有飞机起飞,有6,判断有没有未起飞的
+				setNextTurn(true, player, rsp)
+			}
+		}
+	} else {
+
+		setNextTurn(false, player, rsp)
+	}
+	rsp.SeatID = &player.SeatId
+	var i1 uint32 = 1
+	var i2 uint32 = 2
+	var i3 uint32 = 3
+	var i4 uint32 = 4
+	rsp.AutoMove = &i1
+	//判断是否是托管
+	var operatePlane *GamePlane
+	//var tg bool =false
+	if player.Status == uint32(message.GameStatus_Player_Status_9) {
+		//tg=false
+		//托管的情况下,就会完全自动走
+		if *rsp.SkipReason == 0 {
+			//只有一架飞机已经起飞,且能行走
+			if len(flyplane) > 0 {
+				rsp.AutoMove = &i4
+				operatePlane = flyplane[0]
+			} else if len(unflyplane) > 0 {
+				if ds == 6 {
+					rsp.AutoMove = &i3
+					operatePlane = unflyplane[0]
+				}
+			}
+		} else if *rsp.SkipReason == 1 {
+			if rsp.SeatID == rsp.NextTurn {
+				rsp.AutoMove = &i2
+				//ThrowTheDice(ws)
+			}
+
+		}
+	} else {
+		//	tg=true
+		//不是托管的情况下只会在单棋子的情况下自动走
+		if *rsp.SkipReason == 0 {
+			//log.Info("len(flyplane)", len(flyplane))
+			//只有一架飞机已经起飞,且能行走
+			if len(flyplane) == 1 {
+				if len(unflyplane) == 0 {
+					//其他飞机都到达了终点的情况自动行走
+					rsp.AutoMove = &i4
+					operatePlane = flyplane[0]
+					//	Move(ws, plane[0].Id)
+				} else {
+					//其他飞机没有起飞,点数不为六,且小于等于终点区自动行走
+					if ds != 6 {
+						rsp.AutoMove = &i4
+						operatePlane = flyplane[0]
+					}
+				}
+			} else if len(flyplane) == 0 {
+				if len(unflyplane) == 1 {
+					if ds == 6 {
+						//其他飞机都到达了终点的情况自动起飞
+						rsp.AutoMove = &i3
+						operatePlane = unflyplane[0]
+						//StartFly(ws, unflyplane.Id)
+					}
+
+				}
+			}
+		} else if *rsp.SkipReason == 1 {
+			if rsp.SeatID == rsp.NextTurn {
+				rsp.AutoMove = &i2
+				//ThrowTheDice(ws)
+			}
+
+		}
+	}
+	var data2 = []*message.PlayerRsp{}
+	for _, value := range room.Players {
+		rsp3 := &message.PlayerRsp{}
+		rsp3.SeatId = &value.SeatId
+		var data1 = []*message.PlaneRsp{}
+		for j := 0; j < len(value.GamePlane); j++ {
+			rsp4 := &message.PlaneRsp{}
+			rsp4.PlaneId = value.GamePlane[j].Id
+			u := uint32(value.GamePlane[j].IsFly)
+			rsp4.PlaneStatus = &u
+			rsp4.CurrentIndex = &value.GamePlane[j].CurPosIndex
+			data1 = append(data1, rsp4)
+		}
+		rsp3.Planes = data1
+		data2 = append(data2, rsp3)
+	}
+	rsp.Players = data2
+	rData, _ := proto.Marshal(rsp) //回包
+	log.Warn("发送骰子数据=======", rsp)
+
+	//下一个人
+	nextPlayer := getPlayerBySeatId(*rsp.NextTurn, room)
+	if room.GameEnd == GamePlaying {
+		//下一个人是自己的时候,才会自动摇骰子
+		if rsp.NextTurn == rsp.SeatID {
+			if *rsp.AutoMove == 2 {
+				BroadInfo(room, int16(message.MSGID_Throw_The_Dice_Rsp), rData)
+				broadInfoSz(nextPlayer)
+
+				//摇到6,下一个行动人还是自己的情况
+				if nextPlayer.Status == uint32(message.GameStatus_Player_Status_9) {
+					time.Sleep(1 * time.Second)
+					if nextPlayer.Status == uint32(message.GameStatus_Player_Status_9) {
+						go ThrowTheDice2(uid)
+					}
+				} else {
+					go ThrowTheDice2(uid)
+				}
+
+			} else if *rsp.AutoMove == 3 {
+				BroadInfo(room, int16(message.MSGID_Throw_The_Dice_Rsp), rData)
+				ticker := time.NewTicker(time.Second * 1)
+				player.GameRoom.ticker = ticker
+				go countdonw(nextPlayer, 2, operatePlane.Id)
+				//	go countdonw(nextPlayer)
+				if nextPlayer.Status == uint32(message.GameStatus_Player_Status_9) {
+					time.Sleep(1 * time.Second)
+					//要判断是不是单棋子自动走,如果只是则不用判断托管
+					if len(flyplane) == 0 && len(unflyplane) == 1 {
+						go StartFly2(uid, operatePlane.Id)
+					} else {
+						if nextPlayer.Status == uint32(message.GameStatus_Player_Status_9) {
+							go StartFly2(uid, operatePlane.Id)
+						}
+					}
+				} else {
+					go StartFly2(uid, operatePlane.Id)
+				}
+			} else if *rsp.AutoMove == 4 {
+				BroadInfo(room, int16(message.MSGID_Throw_The_Dice_Rsp), rData)
+				ticker := time.NewTicker(time.Second * 1)
+				player.GameRoom.ticker = ticker
+				go countdonw(nextPlayer, 3, operatePlane.Id)
+				//go countdonw(nextPlayer)
+				if nextPlayer.Status == uint32(message.GameStatus_Player_Status_9) {
+					time.Sleep(1 * time.Second)
+					//	if nextPlayer.Status == uint32(message.GameStatus_Player_Status_9) {
+					if len(flyplane) == 1 && len(unflyplane) == 0 {
+						go Move2(uid, operatePlane.Id)
+					} else {
+						if nextPlayer.Status == uint32(message.GameStatus_Player_Status_9) {
+							go Move2(uid, operatePlane.Id)
+						}
+					}
+
+					//}
+				} else {
+					go Move2(uid, operatePlane.Id)
+				}
+
+			} else if *rsp.AutoMove == 1 {
+				log.Info("下一个人是自己行动的时候,要自己选择棋子起飞,或者选择棋子行走")
+				BroadInfo(room, int16(message.MSGID_Throw_The_Dice_Rsp), rData)
+				ticker := time.NewTicker(time.Second * 1)
+				player.GameRoom.ticker = ticker
+				if len(flyplane) > 0 {
+					go countdonw(nextPlayer, 3, flyplane[0].Id)
+				} else {
+					go countdonw(nextPlayer, 2, unflyplane[0].Id)
+				}
+
+				//broadInfoSz(nextPlayer)
+			}
+		} else {
+			BroadInfo(room, int16(message.MSGID_Throw_The_Dice_Rsp), rData)
+			log.Info("player======,", player.SeatId)
+			log.Info("nextPlayer========,", *rsp.NextTurn)
+			broadInfoSz(nextPlayer)
+			if nextPlayer.Status == uint32(message.GameStatus_Player_Status_9) {
+
+				time.Sleep(1 * time.Second)
+				if nextPlayer.Status == uint32(message.GameStatus_Player_Status_9) {
+					go ThrowTheDice2(nextPlayer.Uid)
+				}
+
+				// } else {
+				// 	if room.GameEnd == GamePlaying {
+				// 		log.Info("下一个人不是自己通知倒计时等待下一位玩家摇筛子")
+				// 		broadInfoSz(nextPlayer)
+				// 	}
+
+			}
+
+		}
+	}
+
+}
+
+// 心跳包
+// 客户端请求起飞
+func StartFly(ws *websocket.Conn, data []byte) {
+	req := &message.PlaneStartReq{}
+	err := proto.Unmarshal(data, req)
+	if err != nil {
+		//	errcode2 := GAME_STATUS_PB_ERR
+		rsp := &message.PbErrorRsp{}
+		rData2, _ := proto.Marshal(rsp) //回包
+		sendData(ws, int16(message.MSGID_Pb_Error_Rsp), rData2)
+		return
+	}
+	uid := ClientUserIds[ws]
+	player := getPlayer(uid)
+	if player.Status == 9 {
+		BroadErrorMsg("托管状态下,不能执行操作", ws)
+		return
+	}
+	StartFly2(uid, req.PlaneID)
+}
+
+func StartFly2(uid string, PlaneId string) {
+	/*defer func() {
+		//捕获test抛出的panic
+		if err := recover(); err != nil {
+			fmt.Println("协程发生错误", err)
+			log.Warn("开始游戏一直没进入游戏数据回退")
+		}
+	}()*/
+	rsp := &message.PlaneStartRsp{}
+
+	//uid := clientUserIds[ws]
+	player := getPlayer(uid)
+	if player==nil{
+		log.Warn("已没有该用户")
+		return
+	}
+	room := player.GameRoom
+	if room.GameEnd == GameEnd {
+		log.Warn("游戏已经结束")
+		return
+	}
+
+	if room.ticker != nil {
+		log.Info("停止倒计时")
+		room.ticker.Stop()
+	}
+	planes := player.GamePlane
+	seatId := player.SeatId
+	//userRoom[player.Uid].ticker.Stop()
+	players := room.Players
+	room.ticker.Stop()
+	for i := 0; i < len(planes); i++ {
+		if planes[i].Id == PlaneId {
+			planes[i].IsFly = 1
+			//如果是seat是0,起飞就是1  seat2 -》14  ,seat3-》27 seat4-》40
+			planes[i].CurPosIndex = 0
+			break
+		}
+	}
+
+	rsp.SeatID = &seatId
+	rsp.PlaneID = PlaneId
+
+	rsp.PlayerNum = uint32(len(players))
+	//如果是6的情况下下一个摇色子的是自己
+	rsp.NextTurn = &seatId
+
+	log.Warn("发送起飞数据", rsp)
+	var data2 = []*message.PlayerRsp{}
+	for _, value := range room.Players {
+		rsp3 := &message.PlayerRsp{}
+		rsp3.SeatId = &value.SeatId
+		var data1 = []*message.PlaneRsp{}
+		for j := 0; j < len(value.GamePlane); j++ {
+			rsp4 := &message.PlaneRsp{}
+			rsp4.PlaneId = value.GamePlane[j].Id
+			u := uint32(value.GamePlane[j].IsFly)
+			rsp4.PlaneStatus = &u
+			rsp4.CurrentIndex = &value.GamePlane[j].CurPosIndex
+			data1 = append(data1, rsp4)
+		}
+		rsp3.Planes = data1
+		data2 = append(data2, rsp3)
+	}
+
+	rsp.Players = data2
+	rData, _ := proto.Marshal(rsp) //回包
+	BroadInfo(room, int16(message.MSGID_Start_Plane_Rsp), rData)
+	broadInfoSz(player)
+	if player.Status == uint32(message.GameStatus_Player_Status_9) {
+		//log.Info("aotumove8")
+
+		time.Sleep(1 * time.Second)
+		if player.Status == uint32(message.GameStatus_Player_Status_9) {
+			go ThrowTheDice2(player.Uid)
+		}
+
+	}
+	// else {
+
+	// 	if room.GameEnd == GamePlaying {
+	// 		broadInfoSz(player)
+	// 	}
+
+	// }
+
+	//倒计时发一个10
+	//countdonw(userRoom[player.Uid].Players, MSGID_START_GAME, 10, player.SeatId)
+}
+
+// 要讨论下棋盘布局
+// 客户端请求行走 逻辑待完善
+func Move(ws *websocket.Conn, data []byte) {
+
+	req := &message.MoveReq{}
+	err := proto.Unmarshal(data, req) //解包
+	if err != nil {
+		//	errcode2 := GAME_STATUS_PB_ERR
+		rsp := &message.PbErrorRsp{}
+		rData2, _ := proto.Marshal(rsp) //回包
+		sendData(ws, int16(message.MSGID_Pb_Error_Rsp), rData2)
+		return
+	}
+	uid := ClientUserIds[ws]
+	player := getPlayer(uid)
+	if player.Status == 9 {
+		BroadErrorMsg("托管状态下,不能执行操作", ws)
+		return
+	}
+	Move2(uid, req.PlaneID)
+}
+
+func Move2(uid string, PlaneId string) {
+	/*defer func() {
+		//捕获test抛出的panic
+		if err := recover(); err != nil {
+			fmt.Println("协程发生错误", err)
+			log.Warn("结束数据回退")
+		}
+	}()*/
+	rsp := &message.MoveRsp{}
+	//玩家都准备完毕了就可以游戏
+	//uid := clientUserIds[ws]
+	player := getPlayer(uid)
+	if nil == player {
+		log.Info("已没有该玩家")
+		return
+	}
+	planes := player.GamePlane
+	
+
+	if player.GameRoom==nil{
+		log.Warn("游戏已经结束")
+		return
+	}
+	room := player.GameRoom
+	if room.GameEnd == GameEnd {
+		log.Warn("游戏已经结束")
+		return
+	}
+	if room.ticker != nil {
+		log.Info("停止倒计时")
+		room.ticker.Stop()
+	}
+	//获取玩家上一次的筛子点数
+	rounds := player.NumberOfRounds[player.Num].NumberOfRounds
+	var rand uint32 = 0
+	if len(rounds) > 0 {
+		u := rounds[len(rounds)-1]
+		//对指针取值
+		rand = *u
+	}
+	players := room.Players
+	room.ticker.Stop()
+	//修改飞机位置
+	planeId, _ := strconv.Atoi(PlaneId)
+	plane := planes[planeId]
+	log.Warn("查询上一次的点数", rand)
+
+	if plane.CurPosIndex+rand > 56 {
+		// log.Warn("超出范围,不能行走")
+		// var data = &message.KickPlayerRsp{}
+		// rData, _ := proto.Marshal(data) //回包
+		// broadInfo(room, int16(message.MSGID_Move_Error_Rsp), rData)
+		BroadErrorMsg("超出范围,不能行走", UserClientIds[uid])
+		return
+	}
+	plane.CurPosIndex = plane.CurPosIndex + rand
+	log.Warn("update plane rand", plane)
+	//到达终点的情况
+	if plane.CurPosIndex == 56 {
+		player.FinishNum = player.FinishNum + 1
+
+		//log.Info("FinishNum", player.FinishNum)
+		//0代表撞子或者到达终点
+		var nilds uint32 = 0
+		player.NumberOfRounds[player.Num].NumberOfRounds = append(player.NumberOfRounds[player.Num].NumberOfRounds, &nilds)
+		rsp2 := &message.FinishEventRsp{SeatId: &player.SeatId, PlaneId: plane.Id}
+		rsp.FinishEvent = rsp2
+		plane.IsFly = 2
+		//获得全部到达终点
+		//代表自己走完了   3 0 1
+		if player.FinishNum == 4 {
+			log.Info("endgameplayer", player.Uid)
+			player.Status = uint32(message.GameStatus_Player_Status_5)
+			room.ArrivalNum = room.ArrivalNum + 1
+			log.Info("ArrivalNum", room.ArrivalNum)
+			//判断是否结束游戏
+			if room.StartPlayerNum < 4 {
+				//rsp.NextTurn = &player.SeatId
+				rsp.NextTurn = nil
+			} else {
+				if room.ArrivalNum == 2 {
+					//userRoom[player.Uid].GameEnd = 2
+					rsp.NextTurn = nil
+				} else {
+					nextSeatId := getNextSeatId(player.SeatId, room)
+					rsp.NextTurn = &nextSeatId
+				}
+
+			}
+		} else {
+			rsp.NextTurn = &player.SeatId
+		}
+	} else {
+		if plane.IsFly == 1 {
+			// 获取飞机所在的下标
+			//获取地图的值标获取对应的格子
+			//未到达终点区的情况,就会发生撞棋
+			if plane.CurPosIndex < 51 {
+				var planess []*GamePlane = []*GamePlane{}
+
+				for _, value := range players {
+					if value.Uid != player.Uid {
+						for i := 0; i < len(value.GamePlane); i++ {
+							if value.GamePlane[i].IsFly == 1 {
+								//不在8个位置上就会发生撞棋
+								i2 := player.GamePlaneIndex[plane.CurPosIndex]
+								if i2 == 1 || i2 == 9 || i2 == 14 || i2 == 22 || i2 == 27 || i2 == 35 || i2 == 40 || i2 == 48 {
+									continue
+								}
+								if value.GamePlaneIndex[value.GamePlane[i].CurPosIndex] == player.GamePlaneIndex[plane.CurPosIndex] {
+									log.Warn("有可以撞的飞机", value.GamePlane[i])
+									planess = append(planess, value.GamePlane[i])
+								}
+							}
+						}
+					}
+
+				}
+
+				if len(planess) == 1 {
+					//if planess[0].Uid != player.Uid {
+					log.Warn("have clash plane", player.Uid)
+					log.Warn("发生了撞棋的被撞飞机uid", planess[0].Uid)
+					//如果只有一个飞机也不是自己的飞机就会发生撞棋
+					planess[0].IsFly = 0
+					planess[0].CurPosIndex = 0
+					player.Kick = player.Kick + 1
+					getPlayer(planess[0].Uid).BeKick = getPlayer(planess[0].Uid).BeKick + 1
+					var i uint32 = 1
+					m := &message.KickPlayerRsp{SeatId: &getPlayer(planess[0].Uid).SeatId, PlaneNum: &i, PlaneID: planess[0].Id}
+					var data = []*message.KickPlayerRsp{}
+					data = append(data, m)
+					rsp2 := &message.TKickEventRsp{PlayerNum: &i, KickPlayer: data}
+					rsp.TKickEvent = rsp2
+					//撞棋下一个行动人还是自己
+					rsp.NextTurn = &player.SeatId
+					//100代表撞子或者达到终点
+					var nilds uint32 = 0
+					player.NumberOfRounds[player.Num].NumberOfRounds = append(player.NumberOfRounds[player.Num].NumberOfRounds, &nilds)
+				} else {
+					seatId := player.SeatId
+					if rand == 6 {
+						rsp.NextTurn = &seatId
+					} else {
+						nextSeatId := getNextSeatId(player.SeatId, room)
+						rsp.NextTurn = &nextSeatId
+					}
+				}
+			} else {
+				seatId := player.SeatId
+				if rand == 6 {
+					rsp.NextTurn = &seatId
+				} else {
+					nextSeatId := getNextSeatId(player.SeatId, room)
+					rsp.NextTurn = &nextSeatId
+				}
+			}
+
+		} else {
+			//游戏出错了,要清除房间数据重来
+			//UpdateRoom(room)
+			log.Warn("飞机没有起飞不能行走", plane)
+			Dissolve_The_Game(player)
+		}
+	}
+	//判断是否撞棋   根据地图上查看对应的位置上有哪些飞机,
+	//获取棋盘内所有玩家是否有飞机在对应的位置
+	rsp.CurPosIndex = &plane.CurPosIndex
+	rsp.PlaneID = PlaneId
+	rsp.Step = &rand
+	//结束游戏就没有下一个人,并且不能行动
+	rsp.PlayerNum = uint32(len(room.Players))
+	rsp.SeatID = &player.SeatId
+	//如果上一次是6的点数,这一次还是自己摇色子  待改
+	var data2 = []*message.PlayerRsp{}
+
+	for _, value := range room.Players {
+		rsp3 := &message.PlayerRsp{}
+		rsp3.SeatId = &value.SeatId
+		var data1 = []*message.PlaneRsp{}
+		for j := 0; j < len(value.GamePlane); j++ {
+			rsp4 := &message.PlaneRsp{}
+			rsp4.PlaneId = value.GamePlane[j].Id
+			u := uint32(value.GamePlane[j].IsFly)
+			rsp4.PlaneStatus = &u
+			rsp4.CurrentIndex = &value.GamePlane[j].CurPosIndex
+			data1 = append(data1, rsp4)
+		}
+		rsp3.Planes = data1
+		data2 = append(data2, rsp3)
+	}
+
+	rsp.Players = data2
+
+	rData, _ := proto.Marshal(rsp) //回包
+	log.Warn("发送移动结果数据", rsp)
+	BroadInfo(room, int16(message.MSGID_Move_Rsp), rData)
+	//log.Info("又发来了请求2")
+
+	//如果下一个玩家是托管状态就直接帮忙投色子 //因为之前的函数没结束,在后面的函数中结束了,导致又会执行一次
+	//判断是否结束游戏
+	if room.GameEnd == GamePlaying {
+		log.Warn("游戏没结束的情况")
+		if room.StartPlayerNum == 4 {
+			//如果已经有人到达终点了
+			if room.ArrivalNum == 2 {
+				log.Warn("4个人的情况下有2人到达了终点,结算游戏进行排名", room.ArrivalNum)
+				if room.RunnerNum == 0 {
+					//将会直接对4个人进行排名 432 缺少1
+					rank34(room, player)
+
+					for _, value := range players {
+						log.Info("结束后玩家状态===", value.Status, value.Uid)
+						if value.Status == uint32(message.GameStatus_Player_Status_5) {
+							//GamePlayers = append(GamePlayers, userRoom[player.Uid].Players[i])
+							if value.Uid != player.Uid {
+								//添加第一名
+								log.Info("添加第一名")
+								room.RankPlayers[len(room.RankPlayers)] = value
+								break
+							}
+						}
+					}
+
+				} else if room.RunnerNum == 1 {
+					//对三个人排名 32
+					addRank(room, player)
+					//rank34(room, player)
+					for _, value := range players {
+						if value.Status == uint32(message.GameStatus_Player_Status_5) {
+							//GamePlayers = append(GamePlayers, userRoom[player.Uid].Players[i])
+							if value.Uid != player.Uid {
+								//	room.RankPlayers = append(room.RankPlayers, value)
+								//添加第一名
+								log.Info("添加第一名", player.Uid)
+								room.RankPlayers[len(room.RankPlayers)] = value
+								break
+							}
+						}
+					}
+					//room.RankPlayers[len(room.Players)] = player
+
+				}
+				endGame(uid)
+			} else {
+				log.Info("下一个玩家", rsp.NextTurn)
+				if rsp.NextTurn != nil {
+					nextPlayer := getPlayerBySeatId(*rsp.NextTurn, room)
+					broadInfoSz(nextPlayer)
+					//log.Info("下一个人的状态", nextPlayer.Status)
+					if nextPlayer.Status == uint32(message.GameStatus_Player_Status_9) {
+						//nextPlayer1 := getPlayerBySeatId(*rsp.NextTurn, uid)
+						time.Sleep(1 * time.Second)
+						if nextPlayer.Status == uint32(message.GameStatus_Player_Status_9) {
+							go ThrowTheDice2(nextPlayer.Uid)
+						}
+
+					}
+
+				}
+			}
+
+		} else if room.StartPlayerNum == 3 {
+
+			if room.ArrivalNum == 1 {
+				log.Warn("三个人结束了游戏")
+				//三个人的情况需要排名
+
+				//4个人的情况下要根据撞棋数排名
+				//先添加失败者最后添加胜者  三个人没有逃跑的情况
+				if room.RunnerNum == 0 {
+					rank34(room, player)
+				} else if room.RunnerNum == 1 {
+					//先添加失败者最后添加胜者  三个人逃跑了一个的情况
+					addRank(room, player)
+
+				}
+				endGame(uid)
+			} else {
+				if rsp.NextTurn != nil {
+					nextPlayer := getPlayerBySeatId(*rsp.NextTurn, room)
+					broadInfoSz(nextPlayer)
+					//log.Info("下一个人的状态", nextPlayer.Status)
+					if nextPlayer.Status == uint32(message.GameStatus_Player_Status_9) {
+						//nextPlayer1 := getPlayerBySeatId(*rsp.NextTurn, uid)
+						time.Sleep(1 * time.Second)
+						if nextPlayer.Status == uint32(message.GameStatus_Player_Status_9) {
+							go ThrowTheDice2(nextPlayer.Uid)
+						}
+
+					}
+
+				}
+			}
+		} else if room.StartPlayerNum == 2 {
+			if room.ArrivalNum == 1 {
+				log.Warn("两个人结束了游戏", len(players))
+				//三个人以下的情况
+				addRank(room, player)
+				endGame(uid)
+
+			} else {
+				if rsp.NextTurn != nil {
+					log.Info("当前玩家", *rsp.SeatID)
+					log.Info("下一个玩家是谁,", *rsp.NextTurn)
+					nextPlayer := getPlayerBySeatId(*rsp.NextTurn, room)
+					broadInfoSz(nextPlayer)
+					//log.Info("下一个人的状态", nextPlayer.Status)
+					if nextPlayer.Status == uint32(message.GameStatus_Player_Status_9) {
+						//nextPlayer1 := getPlayerBySeatId(*rsp.NextTurn, uid)
+						time.Sleep(1 * time.Second)
+						if nextPlayer.Status == uint32(message.GameStatus_Player_Status_9) {
+							go ThrowTheDice2(nextPlayer.Uid)
+						}
+
+					}
+
+				}
+			}
+		}
+
+	}
+
+}
+
+func addRank(room *GameRoom, player *GamePlayer) {
+	players := room.Players
+
+	for _, value := range players {
+		//log.Warn("人员状态", value.Uid)
+		if value.Status == uint32(message.GameStatus_Player_Status_3) || value.Status == uint32(message.GameStatus_Player_Status_9) {
+			//还在玩的是3名
+			log.Info("添加第三名", value.Uid)
+			room.RankPlayers[len(room.RankPlayers)] = value
+			break
+		}
+	}
+	//先添加失败者最后添加胜者
+	log.Info("添加第er名", player.Uid)
+	room.RankPlayers[len(room.RankPlayers)] = player
+}
+
+func rank34(room *GameRoom, player *GamePlayer) {
+	var GamePlayers = []*GamePlayer{}
+	// for i := 0; i < len(players); i++ {
+	// 	if players[i].Status != uint32(message.GameStatus_Player_Status_5) && players[i].Status != uint32(message.GameStatus_Player_Status_6) && players[i].Status != uint32(message.GameStatus_Player_Status_8) {
+	// 		GamePlayers = append(GamePlayers, players[i])
+	// 	}
+	// }
+
+	for _, value := range room.Players {
+		// if value.Status != uint32(message.GameStatus_Player_Status_5) && value.Status != uint32(message.GameStatus_Player_Status_6) && value.Status != uint32(message.GameStatus_Player_Status_8) {
+		// 	GamePlayers = append(GamePlayers, value)
+		// }
+		if value.Status == 3 || value.Status == 9 {
+			log.Info("添加第一名,第二名玩家", value.SeatId)
+			GamePlayers = append(GamePlayers, value)
+		}
+	}
+	if GamePlayers[0].FinishNum > GamePlayers[1].FinishNum {
+		log.Warn("四个人结束了游戏")
+
+		//room.RankPlayers = append(room.RankPlayers, GamePlayers[0])
+		room.RankPlayers[len(room.RankPlayers)] = GamePlayers[1]
+		room.RankPlayers[len(room.RankPlayers)] = GamePlayers[0]
+	} else if GamePlayers[0].FinishNum < GamePlayers[1].FinishNum {
+		//room.RankPlayers = append(room.RankPlayers, GamePlayers[0])
+		//	room.RankPlayers = append(room.RankPlayers, GamePlayers[1])
+		room.RankPlayers[len(room.RankPlayers)] = GamePlayers[0]
+		room.RankPlayers[len(room.RankPlayers)] = GamePlayers[1]
+	} else if GamePlayers[0].FinishNum == GamePlayers[1].FinishNum {
+		var total0 uint32 = 0
+		for i := 0; i < len(GamePlayers[0].GamePlane); i++ {
+			if GamePlayers[0].GamePlane[i].IsFly == 1 {
+				if GamePlayers[0].GamePlane[i].CurPosIndex > total0 {
+					total0 = GamePlayers[0].GamePlane[i].CurPosIndex
+				}
+			}
+
+		}
+		var total1 uint32 = 0
+		for i := 0; i < len(GamePlayers[1].GamePlane); i++ {
+			if GamePlayers[1].GamePlane[i].IsFly == 1 {
+				if GamePlayers[1].GamePlane[i].CurPosIndex > total0 {
+					total1 = GamePlayers[1].GamePlane[i].CurPosIndex
+				}
+			}
+		}
+		if total0 > total1 {
+			// room.RankPlayers = append(room.RankPlayers, GamePlayers[1])
+			// room.RankPlayers = append(room.RankPlayers, GamePlayers[0])
+			room.RankPlayers[len(room.RankPlayers)] = GamePlayers[1]
+			room.RankPlayers[len(room.RankPlayers)] = GamePlayers[0]
+		} else if total0 < total1 {
+			// room.RankPlayers = append(room.RankPlayers, GamePlayers[0])
+			// room.RankPlayers = append(room.RankPlayers, GamePlayers[1])
+			room.RankPlayers[len(room.RankPlayers)] = GamePlayers[0]
+			room.RankPlayers[len(room.RankPlayers)] = GamePlayers[1]
+		} else {
+			room.RankPlayers[len(room.RankPlayers)] = GamePlayers[0]
+			room.RankPlayers[len(room.RankPlayers)] = GamePlayers[1]
+		}
+	}
+	//room.RankPlayers = append(room.RankPlayers, player)
+	log.Info("添加第二名")
+	if player != nil {
+		room.RankPlayers[len(room.RankPlayers)] = player
+	}
+
+}
+
+// 客户端通知托管
+func Trusteeship(ws *websocket.Conn, data []byte) {
+	req := &message.TrusteeshipReq{}
+	proto.Unmarshal(data, req) //解包
+	rsp := &message.TrusteeshipRsp{}
+
+	//玩家都准备完毕了就可以游戏
+	//uid := clientUserIds[ws]
+	rsp.Trust = req.Trust
+	uid := ClientUserIds[ws]
+	player := getPlayer(uid)
+	if rsp.Trust {
+		player.Status = uint32(message.GameStatus_Player_Status_9)
+	} else {
+		player.Status = uint32(message.GameStatus_Player_Status_3)
+	}
+	rsp.SeatID = &player.SeatId
+	rData, _ := proto.Marshal(rsp) //回包
+	BroadInfo(player.GameRoom, int16(message.MSGID_Trusteeship_Rsp), rData)
+}
+
+func Quit(uid string) {
+	rsp := &message.QuitRsp{}
+	player := getPlayer(uid)
+	if nil == player {
+		BroadErrorMsg("该玩家已退出", UserClientIds[uid])
+		return
+	}
+
+	room := player.GameRoom
+	if room == nil {
+		BroadErrorMsg("该玩家已退出房间", UserClientIds[uid])
+		return
+	}
+
+
+	rsp.SeatID = &player.SeatId
+	rsp.PlayerStatus = player.Status
+	rsp.Uid=player.Uid
+	rData, _ := proto.Marshal(rsp) //回包
+	BroadInfo(room, int16(message.MSGID_Quit_Rsq), rData)
+	if room.GameEnd==0{
+		rsp3 := &message.RoomQuitUserRsp{}
+		rsp3.Uid = player.Uid
+		rData3, _ := proto.Marshal(rsp3) //回包
+		BroadInfoRoom(player.GameRoom, int16(message.MSGID_Room_Quit_Rsp), rData3)
+	}
+	
+	// for key, v := range room.Players {
+	// 	if v.Uid==v.Uid{
+
+	// 	}
+	// }
+	//没走完逃跑的情况下
+
+	uuid, _ := strconv.Atoi(player.Uid)
+	//广播退出游戏
+	log.Info("玩家退出")
+	var key2 int
+	//清除玩家状态
+
+	if len(player.GameRoom.Players) == 0 {
+		Dissolve_The_Game(player)
+	} else {
+		for key, value := range player.GameRoom.Players {
+			log.Info("player----", player.Uid)
+			if player.Uid == value.Uid {
+				//	player.GameRoom.Players = append(player.GameRoom.Players[:i], player.GameRoom.Players[i+1:]...)
+
+				if player.GameRoom.Homeowner == uuid {
+					log.Info("查看房主信息")
+					key2 = key
+					if key2 == 0 {
+						if player.GameRoom.Players[1] != nil {
+							uid, _ := strconv.Atoi(player.GameRoom.Players[1].Uid)
+							player.GameRoom.Homeowner = uid
+						} else if player.GameRoom.Players[2] != nil {
+							uid, _ := strconv.Atoi(player.GameRoom.Players[2].Uid)
+							player.GameRoom.Homeowner = uid
+						} else if player.GameRoom.Players[3] != nil {
+							uid, _ := strconv.Atoi(player.GameRoom.Players[3].Uid)
+							player.GameRoom.Homeowner = uid
+						}
+					} else if key2 == 1 {
+						if player.GameRoom.Players[2] != nil {
+							uid, _ := strconv.Atoi(player.GameRoom.Players[2].Uid)
+							player.GameRoom.Homeowner = uid
+						} else if player.GameRoom.Players[3] != nil {
+							uid, _ := strconv.Atoi(player.GameRoom.Players[3].Uid)
+							player.GameRoom.Homeowner = uid
+						} else if player.GameRoom.Players[0] != nil {
+							uid, _ := strconv.Atoi(player.GameRoom.Players[0].Uid)
+							player.GameRoom.Homeowner = uid
+						}
+					} else if key2 == 2 {
+						if player.GameRoom.Players[3] != nil {
+							uid, _ := strconv.Atoi(player.GameRoom.Players[3].Uid)
+							player.GameRoom.Homeowner = uid
+						} else if player.GameRoom.Players[0] != nil {
+							uid, _ := strconv.Atoi(player.GameRoom.Players[0].Uid)
+							player.GameRoom.Homeowner = uid
+						} else if player.GameRoom.Players[1] != nil {
+							uid, _ := strconv.Atoi(player.GameRoom.Players[1].Uid)
+							player.GameRoom.Homeowner = uid
+						}
+					} else if key2 == 3 {
+						if player.GameRoom.Players[0] != nil {
+							uid, _ := strconv.Atoi(player.GameRoom.Players[0].Uid)
+							player.GameRoom.Homeowner = uid
+						} else if player.GameRoom.Players[1] != nil {
+							uid, _ := strconv.Atoi(player.GameRoom.Players[1].Uid)
+							player.GameRoom.Homeowner = uid
+						} else if player.GameRoom.Players[2] != nil {
+							uid, _ := strconv.Atoi(player.GameRoom.Players[2].Uid)
+							player.GameRoom.Homeowner = uid
+						}
+					}
+					player.GameRoom.Players[key].Status = 0
+					//player.Status = status
+					uuod := strconv.Itoa(player.GameRoom.Homeowner)
+					log.Info("玩家是否移交房主", player.GameRoom.Mode)
+					if player.GameRoom.Mode == 1 {
+						rsp2 := &message.RoomChangeOfHomeownerRsp{}
+						rsp2.Uid = uuod
+						rData4, _ := proto.Marshal(rsp2) //回包
+						log.Info("广播玩家移交房主", player.GameRoom.Mode)
+						BroadInfoRoom(player.GameRoom, int16(message.MSGID_Room_Change_Of_Homeowner_Rsp), rData4)
+					}
+
+					break
+				}
+			}
+		}
+	}
+
+	//先判断游戏有没有结束
+	if room.GameEnd == GamePlaying {
+		room.PlayerNum = room.PlayerNum - 1
+		//player.GameRoom = nil
+		if player.Status == uint32(message.GameStatus_Player_Status_10) {
+			for i := 0; i < len(room.GzPlayers); i++ {
+				if room.GzPlayers[i].Uid == uid {
+					room.GzPlayers = append(room.GzPlayers[:i], room.GzPlayers[i+1:]...)
+					i-- // 删除元素后,需要减少索引
+					break
+				}
+			}
+
+		} else {
+			//delete(room.Players, int(player.SeatId))
+			//是否完全达到终点
+			if player.Status == 5 {
+				//player.Status = uint32(message.GameStatus_Player_Status_6)
+				//player.Status = 0
+				//要讲排名插入头插
+				//胜利后逃跑如何给奖励 bug
+				//不会影响游戏结算
+				//只有4个人的情况下,第一名离开,才会有这情况
+				room.RankPlayers[3] = player
+			} else {
+
+				room.RunnerNum = room.RunnerNum + 1
+
+				players := room.Players
+				//index越小,排名越后
+				//room.RankPlayers = append(room.RankPlayers, player)
+				log.Info("add rankplayer====", player.SeatId)
+				room.RankPlayers[len(room.RankPlayers)] = player
+				if room.StartPlayerNum == 2 {
+					//log.Warn("两个人的房间直接结束游戏", room)
+					//头插
+					for i := 0; i < len(players); i++ {
+						if players[i] != nil {
+							if players[i].Uid != player.Uid {
+								//room.RankPlayers = append(room.RankPlayers, players[i])
+								room.RankPlayers[len(room.RankPlayers)] = players[i]
+							}
+						}
+
+					}
+					endGame(uid)
+				} else if room.StartPlayerNum == 3 {
+
+					if room.RunnerNum == 2 {
+						log.Warn("3个人情况下逃跑了两个", room.RunnerNum)
+						for i := 0; i < len(players); i++ {
+							if players[i] != nil {
+								if players[i].Uid != player.Uid {
+									//room.RankPlayers = append(room.RankPlayers, players[i])
+									room.RankPlayers[len(room.RankPlayers)] = players[i]
+								}
+							}
+
+						}
+
+						endGame(uid)
+					} else {
+						if room.ticker != nil {
+							room.ticker.Stop()
+						}
+
+						seatId3 := getNextSeatId(player.SeatId, room)
+						log.Info("返回的seatId", seatId3)
+						player2 := getPlayerBySeatId(seatId3, player.GameRoom)
+						log.Info("玩家退出导致的托管倒计时", player2.SeatId)
+						broadInfoSz(player2)
+					}
+				} else if room.StartPlayerNum == 4 {
+
+					if room.RunnerNum == 2 {
+						//
+						player.Status = 0
+						rank34(room, nil)
+						//addRank(room, player)
+						endGame(uid)
+					} else {
+						if room.ticker != nil {
+							room.ticker.Stop()
+						}
+						seatId2 := getNextSeatId(player.SeatId, room)
+						log.Info("返回的seatId", seatId2)
+						player2 := getPlayerBySeatId(seatId2, player.GameRoom)
+						//player2 := getPlayerBySeatId(player.SeatId, room)
+						log.Info("玩家退出导致的托管2倒计时", player2.SeatId)
+						broadInfoSz(player2)
+					}
+				}
+			}
+
+		}
+
+	}
+	//房主退出来的话,其他玩家没有进房就会直接解散房间
+	log.Info("删除用户", player.Uid,len(room.Players))
+	if player.GameRoom != nil {
+		 for key, v := range player.GameRoom.Players {
+		 	if v.Uid == player.Uid {
+		 		delete(player.GameRoom.Players, key)
+		 	}
+		 }
+		delete(player.GameRoom.RoomPlayers, player.Uid)
+	}
+
+	//log.Info("查看删除用户", player.GameRoom.Players[int(player.SeatId)])
+
+	delete(GamePlayers, player.Uid)
+	delete(UserClientIds, uid)
+	delete(ClientUserIds, UserClientIds[uid])
+	if len(room.Players) == 0 {
+		Dissolve_The_Game(player)
+	}
+}
+
+// 退出游戏
+func QuitGame(ws *websocket.Conn, data []byte) {
+	req := &message.QuitReq{}
+	_ = proto.Unmarshal(data, req) //解包
+
+	//要加入逻辑,将不统计此人数据
+
+	//玩家都准备完毕了就可以游戏
+	uid := ClientUserIds[ws]
+	Quit(uid)
+
+}
+
+func MyHeartBeatReq(ws *websocket.Conn, data []byte) {
+	/*player := G.playerMng.GetPlayerByClientId(clientId)
+	if player != nil {
+		player.LastHeartbeat = time.Now().Unix()
+	}*/
+	//
+	uid := ClientUserIds[ws]
+	player := getPlayer(uid)
+	if player != nil {
+		player.LastHeartbeat = time.Now()
+		log.Info("收到了心跳包",player.Uid)
+		
+	}
+	rsp2 := &message.HeartbeatPush{}
+			rData2, _ := proto.Marshal(rsp2) //回包
+		sendData(ws,int16(message.MSGID_MSGID_Heartbeat_Push_Rsp),rData2)
+	//5分钟清理一次socket无用连接
+	//长时间没有收到用户消息就清理掉对应的socket
+}
+
+func BroadInfo(room *GameRoom, cmd int16, rData []byte) {
+
+	if room != nil {
+		//判断房主在不在游戏房间,不在也要通知
+		for _, value := range room.Players {
+			//log.Info("房间内玩家", value.Uid)
+			//返回筛子点数广播
+			ws := UserClientIds[value.Uid]
+			if nil != ws {
+				sendData(ws, cmd, rData)
+			}
+		}
+
+		for i := 0; i < len(room.GzPlayers); i++ {
+			//返回筛子点数广播
+			ws := UserClientIds[room.GzPlayers[i].Uid]
+			if nil != ws {
+				sendData(ws, cmd, rData)
+			}
+		}
+
+		// for _, player := range room.RoomPlayers {
+		// 	ws := UserClientIds[player.Uid]
+		// 	if nil != ws {
+		// 		sendData(ws, cmd, rData)
+		// 	}
+		// }
+	}
+
+}
+func BroadInfoRoom(room *GameRoom, cmd int16, rData []byte) {
+
+	if room != nil {
+
+		for _, player := range room.RoomPlayers {
+			log.Info("房间内玩家", player.Uid)
+			ws := UserClientIds[player.Uid]
+			//log.Info("ws=====", ws)
+			if nil != ws {
+				sendData(ws, cmd, rData)
+			}
+		}
+	}
+
+}
+
+// 广播除某些uid外的
+func broadInfoExceptUid(room *GameRoom, cmd int16, rData []byte, uid string) {
+	if room != nil {
+
+		for _, player := range room.RoomPlayers {
+			if player.Uid != uid {
+				ws := UserClientIds[player.Uid]
+				//log.Info("ws=====", ws)
+				if nil != ws {
+					sendData(ws, cmd, rData)
+				}
+			}
+
+		}
+	}
+}
+
+//退出游戏
+
+func packageData2(cmd int16, protoData []byte, dataSize int64) []byte {
+	//int32类型大小为 4 字节
+	pkgsize := dataSize + 6
+	pkglength := dataSize + 2
+	datapkg := make([]byte, pkgsize)
+	//数据长度  18
+	datapkg[0] = byte((pkglength >> 24) & 0xFF)
+	datapkg[1] = byte((pkglength >> 16) & 0xFF)
+	datapkg[2] = byte((pkglength >> 8) & 0xFF)
+	datapkg[3] = byte(pkglength & 0xFF)
+	datapkg[4] = byte((cmd >> 8) & 0xFF)
+	datapkg[5] = byte(cmd & 0xFF)
+	//int16类型大小为 2 字节
+	//数据实体
+	for i, _ := range protoData {
+		datapkg[i+6] = protoData[i]
+	}
+	protoBytes := make([]byte, len(datapkg)-6)
+	for i, _ := range protoBytes {
+		protoBytes[i] = datapkg[i+6]
+	}
+	return datapkg
+}
+
+// 发送单个玩家
+func sendData(ws *websocket.Conn, cmd int16, rData []byte) {
+	defer func() {
+		err := recover()
+		if err != nil {
+			//	fmt.Println("recover panic, err:", err)
+			//log.Info("游戏出错,房间重置")
+			//	Dissolve_The_Game(gamePlayers[ClientUserIds[ws]])
+			log.Info("发送失败说明玩家断开连接不用管,进行局部异常捕获")
+		}
+	}()
+	pkg_data := packageData2( //匹配服务
+		cmd, //返回房间列表
+		rData, int64(len(rData)))
+	if ws != nil {
+
+		error := ws.WriteMessage(websocket.BinaryMessage, pkg_data)
+		if error != nil {
+			//Dissolve_The_Game(gamePlayers[ClientUserIds[ws]])
+			//log.Info("发送失败,直接按退出处理")
+			if GamePlayers[ClientUserIds[ws]] != nil {
+				if GamePlayers[ClientUserIds[ws]].Status != 0 {
+					GamePlayers[ClientUserIds[ws]].Status = 0
+					log.Info("请求退出")
+					//QuitRoom(GamePlayers[ClientUserIds[ws]], ws, 0)
+				}
+
+			}
+
+			//delete(gamePlayers,ClientUserIds[ws])
+			//delete(UserClientIds, ClientUserIds[ws])
+			//delete(ClientUserIds, ws)
+
+		}
+	}
+
+}
+
+func GetRange(j int32, k int32, data []*scheme.SzItem) []*scheme.SzItem {
+	//	data := scp.dataList
+	//var szs map[int32]*SzItem = make(map[int32]*SzItem)
+	var szs = []*scheme.SzItem{}
+	for i := 0; i < len(data); i++ {
+		if data[i].FinialPlane == j {
+			if data[i].PlayerNum == k {
+				szs = append(szs, data[i])
+				//szs[data[i].Ds]=data[i]
+			}
+		}
+	}
+	return szs
+}
+
+// 最后一架飞机,玩家人数小于4 ,不在终点区
+func GetRange2(j int32, k int32, l int32, data []*scheme.SzItem) []*scheme.SzItem {
+	//data := scp.dataList
+	//var szs map[int32]*SzItem = make(map[int32]*SzItem)
+	var szs = []*scheme.SzItem{}
+	for i := 0; i < len(data); i++ {
+		//121 是最后一个飞机,不是最后一个玩家,是终点区
+		if data[i].FinialPlane == j {
+			if data[i].PlayerNum == k {
+				if data[i].FinialArea == l {
+					szs = append(szs, data[i])
+				}
+
+				//szs[data[i].Ds]=data[i]
+			}
+		}
+	}
+	return szs
+}
+
+// 最后一架飞机,在终点区,点数为1点的情况
+func GetRange4(j int32, l int32, m int32, data []*scheme.SzItem) []*scheme.SzItem {
+	//	data := scp.dataList
+	//var szs map[int32]*SzItem = make(map[int32]*SzItem)
+	var szs = []*scheme.SzItem{}
+	for i := 0; i < len(data); i++ {
+		if data[i].FinialPlane == j {
+			if data[i].FinialArea == l {
+				if data[i].FinialPoint == m {
+					szs = append(szs, data[i])
+				}
+				//szs[data[i].Ds]=data[i]
+			}
+		}
+	}
+	return szs
+}
+func GetUserMoneyReq(ws *websocket.Conn, data []byte) {
+	//var gamePlane = GamePlane{Id: strconv.Itoa(j), Uid: uid, IsFly: 0}
+	req := &message.GetUserMoneyReq{}
+	_ = proto.Unmarshal(data, req) //解包
+	uid2, _ := strconv.Atoi(req.Uid)
+	//userrsp := Utils.GetUserInfoData(uid2)
+	userrsp := Utils.GetFbData(uid2,"","",0)
+	if userrsp.Code == 666 {
+		BroadErrorMsg("获取金币出错", ws)
+		return
+	}
+	rsp2 := &message.GetUserMoneyRsp{}
+	var coin = uint32(userrsp.Data[0].GoldCoins)
+	rsp2.Money = &coin
+	rData4, _ := proto.Marshal(rsp2) //回包
+	//return userrsp.Data[0].GoldCoins
+	sendData(ws, int16(message.MSGID_Get_User_Money_Rsp), rData4)
+}
+func createPlane(j int, uid string) GamePlane {
+	var gamePlane = GamePlane{Id: strconv.Itoa(j), Uid: uid, IsFly: 0}
+	return gamePlane
+}
+
+func setNextTurn(canmove bool, player *GamePlayer, rsp *message.ThrowTheDiceRsp) {
+	if canmove {
+		skip := uint32(0)
+		rsp.SkipReason = &skip
+		rsp.NextTurn = &player.SeatId
+	} else {
+		skip := uint32(1)
+		rsp.SkipReason = &skip
+		nextSeatId := getNextSeatId(player.SeatId, player.GameRoom)
+		log.Info("获取下一个人的uid", nextSeatId)
+		rsp.NextTurn = &nextSeatId
+	}
+
+}

+ 1737 - 0
Server/GameServer/Server/PlaneGame/Module/Player.go

@@ -0,0 +1,1737 @@
+package Module
+
+import (
+	"Server-Core/Server/GameServer/Server/PlaneGame/Utils"
+	message "Server-Core/Server/Message"
+	"encoding/json"
+
+	"strconv"
+	"sync"
+	"time"
+
+	"fmt"
+
+	"github.com/gin-gonic/gin"
+	"github.com/golang/protobuf/proto"
+	"github.com/gorilla/websocket"
+	log "github.com/sirupsen/logrus"
+
+	rtctokenbuilder "github.com/AgoraIO/Tools/DynamicKey/AgoraDynamicKey/go/src/rtctokenbuilder2"
+)
+
+type GamePlayer struct {
+	Ticker         *time.Ticker
+	Id             string
+	Name           string
+	HeadImg        string
+	Uid            string
+	GamePlane      []*GamePlane
+	GamePlaneIndex []int
+	GameRoom       *GameRoom
+	GameRoomId     int    //上一把的房间id
+	Status         uint32 // 玩家的当前状态, 0、大厅,1 表示匹配,2: 进入房间已落座, 3: ready, 4: play, 5: 胜利后观战, 6: 胜利后离开,7: 组队逃跑,8: 逃跑,9托管状态,10观战,11进房未落座,12已建房,未拉取房间信息,13结算待退出,14已开游戏未进房
+	Num            int    //代表当前第几轮
+	SeatId         uint32
+	NumberOfRounds []*GameNumberOfRounds
+	Money          uint32    //金额
+	Kick           uint32    //撞棋数
+	BeKick         uint32    //被撞棋数
+	FinishNum      uint32    //到达终点数
+	LastHeartbeat  time.Time //最后一次心跳时间
+	PlayerNum      uint32    //玩家人数
+	//Status2        uint32    // 玩家的当前状态, 1代表没有开启任何房间,2在匹配中,3是在房间内
+	MaxNum       int    //最大房间人数
+	Mode         int    //游戏模式
+	AdmissionFee uint32 //入场费
+	RoomType     int
+}
+
+// 根据uid查询websocket连接信息
+var UserClientIds map[string]*websocket.Conn = make(map[string]*websocket.Conn)
+
+// 根据websocket连接信息查询uid
+var ClientUserIds map[*websocket.Conn]string = make(map[*websocket.Conn]string)
+var GamePlayers = make(map[string]*GamePlayer)
+
+// 飞机
+type GamePlane struct {
+	Id          string
+	CurPosIndex uint32
+	IsFly       int //0代表未起飞,1已经起飞,2到达终点
+	Uid         string
+}
+type GameNumberOfRounds struct {
+	Num            int
+	NumberOfRounds []*uint32
+}
+type RequestUserData struct {
+	Data []GamePlayer `json:"data"`
+}
+
+// 根据seatId获取房间内对应玩家
+func getPlayerBySeatId(seatId uint32, room *GameRoom) *GamePlayer {
+	//	uid := clientUserIds[ws]
+	for _, value := range room.Players {
+		log.Info("每一个人的seatId", value.SeatId)
+		if seatId == value.SeatId {
+			return value
+		}
+	}
+	return nil
+	//return room.Players[int(seatId)]
+}
+
+// 根据uid获取房间内对应玩家
+func getPlayer(uid string) *GamePlayer {
+	return GamePlayers[uid]
+}
+
+func getNextSeatId(seatId uint32, room *GameRoom) uint32 {
+	// if seatId < uint32(room.StartPlayerNum-1) {
+	// 	seatId = seatId + 1
+	// } else {
+	// 	seatId = 0
+	// }
+	// for _, value := range room.Players {
+
+	// 	if value.SeatId == seatId {
+	// 		if value.Status == uint32(message.GameStatus_Player_Status_5) || value.Status == uint32(message.GameStatus_Player_Status_6) || value.Status == uint32(message.GameStatus_Player_Status_8) || value.Status == 0 {
+	// 			seatId = getNextSeatId(seatId, room)
+	// 			break
+	// 		} else {
+	// 			{
+	// 				return seatId
+	// 			}
+	// 		}
+	// 	}
+	// }
+	if seatId == 0 {
+		for _, v := range room.Players {
+			if v.Status == 3 || v.Status == 9 {
+				if v.SeatId == 1 {
+					return 1
+				}
+			}
+
+		}
+		for _, v := range room.Players {
+			if v.Status == 3 || v.Status == 9 {
+				if v.SeatId == 2 {
+					return 2
+				}
+			}
+
+		}
+		for _, v := range room.Players {
+			if v.Status == 3 || v.Status == 9 {
+				if v.SeatId == 3 {
+					return 3
+				}
+			}
+
+		}
+
+	} else if seatId == 1 {
+		for _, v := range room.Players {
+			if v.Status == 3 || v.Status == 9 {
+				if v.SeatId == 2 {
+					return 2
+				}
+			}
+		}
+		for _, v := range room.Players {
+			if v.Status == 3 || v.Status == 9 {
+				if v.SeatId == 3 {
+					return 3
+				}
+			}
+		}
+		for _, v := range room.Players {
+			if v.Status == 3 || v.Status == 9 {
+				if v.SeatId == 0 {
+					return 0
+				}
+			}
+		}
+	} else if seatId == 2 {
+		for _, v := range room.Players {
+			if v.Status == 3 || v.Status == 9 {
+				if v.SeatId == 3 {
+					return 3
+				}
+			}
+		}
+		for _, v := range room.Players {
+			if v.Status == 3 || v.Status == 9 {
+				if v.SeatId == 0 {
+					return 0
+				}
+			}
+		}
+		for _, v := range room.Players {
+			if v.Status == 3 || v.Status == 9 {
+				if v.SeatId == 1 {
+					return 1
+				}
+			}
+		}
+	} else if seatId == 3 {
+		for _, v := range room.Players {
+			if v.Status == 3 || v.Status == 9 {
+				if v.SeatId == 0 {
+					return 0
+				}
+			}
+		}
+		for _, v := range room.Players {
+			if v.Status == 3 || v.Status == 9 {
+				if v.SeatId == 1 {
+					return 1
+				}
+			}
+		}
+		for _, v := range room.Players {
+			if v.Status == 3 || v.Status == 9 {
+				if v.SeatId == 2 {
+					return 2
+				}
+			}
+		}
+	}
+
+	return seatId
+
+}
+
+// 返回玩家数据,等待玩家准备完毕
+func GetUserInfo(ws *websocket.Conn, data []byte) {
+
+	var uid = ClientUserIds[ws]
+	req := &message.GetUserInfoReq{}
+	proto.Unmarshal(data, req)
+	rsp := &message.GetUserInfoRsp{}
+	errcode := uint32(message.GameStatus_GAME_STATUS_OK)
+	rsp.Result = &errcode
+	log.Info("获取用户数据", uid)
+	//测试期间:没有账号则创建账号和密码,有账号则验证密码
+	//先验证账号不能为空
+	lock4.Lock()
+	//gameplayer := getPlayer(req.Uid)
+	//	gameplayer := GamePlayers[req.Uid]
+	if len(uid) == 0 {
+		room := gameRooms[int(req.RoomId)]
+		//加入观战玩家
+		UserClientIds[uid] = ws
+		ClientUserIds[ws] = uid
+		var gameplayer = &GamePlayer{}
+
+		gameplayer.Uid = uid
+
+		//room := gameRooms[int(gameplayer.GameRoom.Id)]
+		if room.GameEnd == 1 {
+			//userRoom[req.Uid] = room
+
+			//查看房间人数
+			var names = []string{}
+			var headImg = []string{}
+			var uids = []string{}
+			var seatId = []uint32{}
+			var playerStatus = []uint32{}
+
+			players := room.Players
+
+			for i := 0; i < len(players); i++ {
+				if players[i] != nil {
+					if players[i].Status == 3 || players[i].Status == 9 {
+						names = append(names, players[i].Name)
+						headImg = append(headImg, players[i].HeadImg)
+						uids = append(uids, players[i].Uid)
+						seatId = append(seatId, players[i].SeatId)
+						playerStatus = append(playerStatus, players[i].Status)
+					}
+				}
+
+			}
+			rsp.Nick = names
+			rsp.HeadUrl = headImg
+			rsp.PlayerID = uids
+			rsp.SeatID = seatId
+			rsp.PlayerStatus = playerStatus
+			rsp.PlayerNum = uint32(len(players))
+			room.GzPlayers = append(room.GzPlayers, gameplayer)
+			var i = uint32(len(room.GzPlayers))
+			rsp.WatchingPlayers = &i
+			rsp.GameType = uint32(room.Mode)
+			rData, _ := proto.Marshal(rsp) //回包
+			log.Info("返回用户信息", rsp)
+			sendData(ws, int16(message.MSGID_Get_User_Info_Rsp), rData)
+			
+			gameplayer.Status = uint32(message.GameStatus_Player_Status_10)
+			var playnum uint32 = uint32(len(players))
+
+		rsp2 := &message.JoinRoomInfoRsp{Nick: gameplayer.Name, HeadUrl: gameplayer.HeadImg, PlayerID: gameplayer.Uid, SeatID: &gameplayer.SeatId, PlayerStatus: gameplayer.Status, PlayerNum: &playnum}
+		log.Info("通知到玩家加入房间", rsp2)
+		rData2, _ := proto.Marshal(rsp2) //回包
+		for _, value := range players {
+			if value.Uid != gameplayer.Uid {
+				if value.Status == uint32(message.GameStatus_Player_Status_3)||value.Status == uint32(message.GameStatus_Player_Status_9) {
+					sendData(UserClientIds[value.Uid], int16(message.MSGID_Join_Room_Info_Rsp), rData2)
+				}
+			}
+		}
+
+		for j := 0; j < len(room.GzPlayers); j++ {
+			if room.GzPlayers[j].Uid != gameplayer.Uid {
+				//
+				//if room.GzPlayers[j].Status == uint32(message.GameStatus_Player_Status_3) || room.GzPlayers[j].Status == uint32(message.GameStatus_Player_Status_10) {
+					sendData(UserClientIds[room.GzPlayers[j].Uid], int16(message.MSGID_Join_Room_Info_Rsp), rData2)
+			//	}
+			}
+		}
+		} else {
+			//返回倒计时
+			room.GzPlayers = append(room.GzPlayers, gameplayer)
+			//查看房间人数
+			var names = []string{}
+			var headImg = []string{}
+			var uids = []string{}
+			var seatId = []uint32{}
+			var playerStatus = []uint32{}
+
+			players := room.Players
+
+			for i := 0; i < len(players); i++ {
+				if players[i] != nil {
+					if players[i].Status == 3 {
+						names = append(names, players[i].Name)
+						headImg = append(headImg, players[i].HeadImg)
+						uids = append(uids, players[i].Uid)
+						seatId = append(seatId, players[i].SeatId)
+						playerStatus = append(playerStatus, players[i].Status)
+					}
+				}
+
+			}
+			rsp.Nick = names
+			rsp.HeadUrl = headImg
+			rsp.PlayerID = uids
+			rsp.SeatID = seatId
+			rsp.PlayerStatus = playerStatus
+			rsp.PlayerNum = uint32(len(players))
+			var time uint32 = 10
+			rsp.Countdown = &time
+			rsp.GameType = uint32(room.Mode)
+			var i = uint32(len(room.GzPlayers))
+			rsp.WatchingPlayers = &i
+			rData, _ := proto.Marshal(rsp) //回包
+			log.Info("返回用户信息", rsp)
+			sendData(ws, int16(message.MSGID_Get_User_Info_Rsp), rData)
+		}
+		
+	} else {
+		gameplayer := GamePlayers[uid]
+		//查看房间人数
+		//room := userRoom[gameplayer.Uid]
+
+		room := gameplayer.GameRoom
+		//room := gameRooms[int(req.RoomId)]
+		var names = []string{}
+		var headImg = []string{}
+		var uids = []string{}
+		var seatId = []uint32{}
+		var playerStatus = []uint32{}
+
+		players := room.Players
+
+		for _, value := range room.Players {
+			log.Info("uid", uid)
+			log.Info("players[i].Uid", value.Uid)
+			if value.Uid == uid {
+				//如果是没有准备第一次进入房间,则会更新玩家座位号,如果是掉线重连
+				//if value.Status == uint32(message.GameStatus_Player_Status_2) || value.Status == uint32(message.GameStatus_Player_Status_1) {
+				if value.Status ==14 {
+					gameplayer.Status = uint32(message.GameStatus_Player_Status_3)
+
+					log.Print("获取room.PlayerNum", room.PlayerNum)
+					//seatId 0 1 2
+					gameplayer.SeatId = uint32(room.PlayerNum)
+					room.PlayerNum = room.PlayerNum + 1
+
+					//lock.Unlock()
+					if len(players) == 2 {
+						if gameplayer.SeatId == 0 {
+							gameplayer.GamePlaneIndex = Maps[0]
+						} else if gameplayer.SeatId == 1 {
+							gameplayer.GamePlaneIndex = Maps[2]
+						}
+					} else if len(players) == 3 {
+						if gameplayer.SeatId == 0 {
+							gameplayer.GamePlaneIndex = Maps[0]
+						} else if gameplayer.SeatId == 1 {
+							gameplayer.GamePlaneIndex = Maps[1]
+						} else if gameplayer.SeatId == 2 {
+							gameplayer.GamePlaneIndex = Maps[2]
+						}
+					} else if len(players) == 4 {
+						if gameplayer.SeatId == 0 {
+							gameplayer.GamePlaneIndex = Maps[0]
+						} else if gameplayer.SeatId == 1 {
+							gameplayer.GamePlaneIndex = Maps[1]
+						} else if gameplayer.SeatId == 2 {
+							gameplayer.GamePlaneIndex = Maps[2]
+						} else if gameplayer.SeatId == 3 {
+							gameplayer.GamePlaneIndex = Maps[3]
+						}
+					}
+
+				}
+			}
+
+			if value.Status == uint32(message.GameStatus_Player_Status_3)||value.Status == uint32(message.GameStatus_Player_Status_9) {
+				names = append(names, value.Name)
+				headImg = append(headImg, value.HeadImg)
+				uids = append(uids, value.Uid)
+				seatId = append(seatId, value.SeatId)
+				playerStatus = append(playerStatus, value.Status)
+			}
+		}
+		rsp.Nick = names
+		rsp.HeadUrl = headImg
+		rsp.PlayerID = uids
+		rsp.SeatID = seatId
+		if gameplayer.Status == 3 {
+			rsp.SelfSeatId = &gameplayer.SeatId
+		}
+//添加观战玩家
+if gameplayer.Status == 10 {
+	room.GzPlayers = append(room.GzPlayers, gameplayer)
+}
+		rsp.PlayerStatus = playerStatus
+		rsp.PlayerNum = uint32(len(players))
+		var i = uint32(len(room.GzPlayers))
+		rsp.WatchingPlayers = &i
+		rsp.GameType = uint32(room.Mode)
+		rData, _ := proto.Marshal(rsp) //回包
+		log.Info("返回用户信息", rsp)
+		sendData(ws, int16(message.MSGID_Get_User_Info_Rsp), rData)
+		
+
+	
+		//广播除本人外的所有在线用户加入房间
+		var playnum uint32 = uint32(len(players))
+
+		rsp2 := &message.JoinRoomInfoRsp{Nick: gameplayer.Name, HeadUrl: gameplayer.HeadImg, PlayerID: gameplayer.Uid, SeatID: &gameplayer.SeatId, PlayerStatus: gameplayer.Status, PlayerNum: &playnum}
+		log.Info("通知到玩家加入房间", rsp2)
+		rData2, _ := proto.Marshal(rsp2) //回包
+
+		for _, value := range players {
+			if value.Uid != gameplayer.Uid {
+				if value.Status == uint32(message.GameStatus_Player_Status_3)||value.Status == uint32(message.GameStatus_Player_Status_9) {
+					sendData(UserClientIds[value.Uid], int16(message.MSGID_Join_Room_Info_Rsp), rData2)
+				}
+			}
+		}
+
+		for j := 0; j < len(room.GzPlayers); j++ {
+			if room.GzPlayers[j].Uid != gameplayer.Uid {
+				//if room.GzPlayers[j].Status == uint32(message.GameStatus_Player_Status_3) || room.GzPlayers[j].Status == uint32(message.GameStatus_Player_Status_10) {
+					sendData(UserClientIds[room.GzPlayers[j].Uid], int16(message.MSGID_Join_Room_Info_Rsp), rData2)
+			//	}
+			}
+		}
+		
+		log.Print("加入房间的人数", len(room.Players))
+		log.Info("加入房间的观战人数", len(room.GzPlayers))
+		//log.Info("房间内的人数", len(room.Players))
+
+		if room.PlayerNum == room.StartPlayerNum {
+			//没有开始游戏才会开始游戏
+			if room.GameEnd == GameNotStarted {
+				for _, value := range room.Players {
+					//初始化飞机
+					var plane = []*GamePlane{}
+					for j := 0; j < 4; j++ {
+						gamePlane := createPlane(j, value.Uid)
+						plane = append(plane, &gamePlane)
+					}
+					value.GamePlane = plane
+				}
+
+				log.Info("广播开始游戏")
+				room.GameEnd = GamePlaying
+				//玩家都准备完毕了就可以游戏
+				if room.ticker != nil {
+					room.ticker.Stop()
+				}
+
+				nextplayer := getPlayerBySeatId(0, room)
+				broadInfoSz(nextplayer)
+			}
+		}
+
+	}
+	lock4.Unlock()
+}
+
+// var lock sync.Mutex
+var lock4 sync.Mutex
+
+// 返回玩家数据,等待玩家准备完毕
+
+func createPlayer(i int, plane []*GamePlane, data []GamePlayer, room *GameRoom) GamePlayer {
+	var gamePlayer = GamePlayer{}
+	gamePlayer.GamePlane = plane
+	gamePlayer.GameRoom = room
+	//gamePlayer.Id = strconv.Itoa(i)
+	gamePlayer.Uid = data[i].Uid
+	gamePlayer.Name = data[i].Name
+	gamePlayer.HeadImg = data[i].HeadImg
+	gamePlayer.Status = uint32(0)
+	//gamePlayer.SeatId = uint32(i)
+	gamePlayer.Money = data[i].Money
+	gamePlayer.FinishNum = 0
+	gamePlayer.Num = 0
+	var rounds = []*GameNumberOfRounds{}
+	var num *GameNumberOfRounds = new(GameNumberOfRounds)
+	var nums = []*uint32{}
+	(*num).Num = 0
+	(*num).NumberOfRounds = nums
+	rounds = append(rounds, num)
+	gamePlayer.NumberOfRounds = rounds
+	return gamePlayer
+}
+func createPlayer2(uid string, ws *websocket.Conn,url string,name string, money uint32) *GamePlayer {
+	var gamePlayer = GamePlayer{}
+
+	//gamePlayer.GameRoom = room
+	//gamePlayer.Id = strconv.Itoa(i)
+	gamePlayer.Uid = uid
+	uid2, _ := strconv.Atoi(uid)
+	//userrsp := Utils.GetUserInfoData(uid2)
+	userrsp := Utils.GetFbData(uid2,url,name,money)
+	log.Printf("查看返回值", userrsp)
+	
+	if userrsp.Code != 200 {
+		BroadErrorMsg("没有该玩家信息", ws)
+		return nil
+	} else {
+		gamePlayer.Name = userrsp.Data[0].NickName
+		gamePlayer.HeadImg = userrsp.Data[0].Avatar
+		gamePlayer.Money = uint32(userrsp.Data[0].GoldCoins)
+	}
+	//log.Printf("查询到的玩家信息", userrsp.Data[0])
+
+	gamePlayer.Status = uint32(0)
+	//gamePlayer.SeatId = uint32(i)
+	//gamePlayer.Status2 = uint32(PlayerIdle)
+	gamePlayer.FinishNum = 0
+	gamePlayer.Num = 0
+
+	var rounds = []*GameNumberOfRounds{}
+	var num *GameNumberOfRounds = new(GameNumberOfRounds)
+	var nums = []*uint32{}
+	(*num).Num = 0
+	(*num).NumberOfRounds = nums
+	rounds = append(rounds, num)
+	gamePlayer.NumberOfRounds = rounds
+	GamePlayers[gamePlayer.Uid] = &gamePlayer
+	return &gamePlayer
+}
+func resetPlayer(gamePlayer *GamePlayer) int {
+
+	//gamePlayer.GameRoom = room
+	//gamePlayer.Id = strconv.Itoa(i)
+
+	uid2, _ := strconv.Atoi(gamePlayer.Uid)
+	userrsp := Utils.GetUserInfoData(uid2)
+	if userrsp.Code != 200 {
+		log.Printf("没有玩家信息")
+
+		//return nil
+		//gamePlayers[gamePlayer.Uid]=nil
+		delete(GamePlayers, gamePlayer.Uid)
+		return 666
+	}
+	log.Printf("查询到的玩家信息", userrsp.Data[0])
+	gamePlayer.Name = userrsp.Data[0].NickName
+	gamePlayer.HeadImg = userrsp.Data[0].Avatar
+	gamePlayer.Money = uint32(userrsp.Data[0].GoldCoins)
+	gamePlayer.Status = uint32(message.GameStatus_Player_Status_1)
+	//gamePlayer.SeatId = uint32(i)
+	//gamePlayer.Status2 = uint32(PlayerIdle)
+	gamePlayer.FinishNum = 0
+	gamePlayer.Num = 0
+
+	var rounds = []*GameNumberOfRounds{}
+	var num *GameNumberOfRounds = new(GameNumberOfRounds)
+	var nums = []*uint32{}
+	(*num).Num = 0
+	(*num).NumberOfRounds = nums
+	rounds = append(rounds, num)
+	gamePlayer.NumberOfRounds = rounds
+	return 200
+	//gamePlayers[gamePlayer.Uid] = &gamePlayer
+	//return &gamePlayer
+}
+
+// 用户登录 建立socket连接
+func Login(ws *websocket.Conn, data []byte) {
+	/*req := &message.UserInfoReq{}
+	proto.Unmarshal(data, req) //解包
+	userClientIds[req.Uid] = ws
+	clientUserIds[ws] = req.Uid
+	var gamePlayer = GamePlayer{Uid: req.Uid, Name: req.Name, HeadImg: req.HeadImg, Money: req.Money}
+	gamePlayers[req.Uid] = &gamePlayer*/
+	//需要携带房间号,如果有的话说明在一个房间,
+	//玩家
+
+}
+
+// 确认一下对接方式
+// 语聊房客户端直接传输roomId给游戏服务器,然后就
+// 根据窗口id 找到对应的窗口
+// 玩家根据游戏窗口加入窗口进行广播
+// 携带窗口id和uid
+func JoinRoomReq(ws *websocket.Conn, data []byte) {
+	//语聊房携带id加入游戏房间
+	//uid := clientUserIds[ws]
+	req := &message.JoinRoomReq{}
+	proto.Unmarshal(data, req) //解包
+	log.Println("获取请求的参数", req)
+	JoinRoom(req.Uid, int(*req.RoomId), ws)
+}
+
+func JoinRoom(uid string, roomId int, ws *websocket.Conn) {
+	var player = GamePlayers[uid]
+	//log.Info("uid", req.Uid)
+
+	//gamePlayer :
+	room := gameRooms[roomId]
+	if room == nil {
+		BroadErrorMsg("房间不存在,无法加入", ws)
+		return
+	} else {
+		if room.Status == RoomIdle {
+			BroadErrorMsg("房间还没开,不能使用", ws)
+			return
+		}
+	}
+
+	if player == nil {
+
+		player = createPlayer2(uid, ws,"","",0)
+		if nil == player {
+			BroadErrorMsg("没有该玩家信息", ws)
+			return
+		}
+
+	} else {
+		if player.Status != 10 {
+			BroadErrorMsg("玩家未拉取房间信息", ws)
+			return
+			// for _, player2 := range room.Players {
+			// 	if player2.Uid == player.Uid {
+			// 		BroadErrorMsg("已加入游戏不能创建游戏房间", ws)
+			// 		return
+			// 	}
+
+			// }
+
+		}
+
+	}
+	lock6.Lock()
+	room.RoomPlayers[player.Uid] = player
+	// ClientUserIds[ws] = req.Uid
+	// UserClientIds[req.Uid] = ws
+	//gamePlayer.Uid = req.Uid
+	rsp4 := &message.JoinRoomInfoRsp{}
+	if len(room.Players) < room.MaxNum {
+
+		var canjoin = true
+		for _, value := range room.Players {
+			log.Printf("查看房间内剩余玩家", value.Uid)
+			if value.Uid == uid {
+				//已加入不能重复加入
+				canjoin = false
+			}
+		}
+		if canjoin {
+			log.Print("加入玩家", player.Uid)
+
+			 if player.Money<room.AdmissionFee{
+			 	BroadErrorMsg("金币不足",ws)
+			 	return
+			 }
+			//delete(room.GzPlayers,player)
+
+			player.GameRoom = room
+			player.AdmissionFee = room.AdmissionFee
+			player.MaxNum = room.MaxNum
+			player.Mode = room.Mode
+			player.Status = uint32(message.GameStatus_Player_Status_2)
+			player.FinishNum = 0
+			player.Num = 0
+			var rounds = []*GameNumberOfRounds{}
+			var num *GameNumberOfRounds = new(GameNumberOfRounds)
+			var nums = []*uint32{}
+			(*num).Num = 0
+			(*num).NumberOfRounds = nums
+			rounds = append(rounds, num)
+			player.NumberOfRounds = rounds
+			//	player.GameRoom = room
+			Rcfcz(player.Uid, room.AdmissionFee, 2)
+			//broadRoomInfo(room, ws)
+			room.RoomPlayers[player.Uid] = player
+			if room.Players[0] == nil {
+				room.Players[0] = player
+				var seat uint32 = 0
+				rsp4.SeatID = &seat
+			} else if room.Players[1] == nil {
+				room.Players[1] = player
+				var seat uint32 = 1
+				rsp4.SeatID = &seat
+			} else if room.Players[2] == nil {
+				room.Players[2] = player
+				var seat uint32 = 2
+				rsp4.SeatID = &seat
+			} else if room.Players[3] == nil {
+				room.Players[3] = player
+				var seat uint32 = 3
+				rsp4.SeatID = &seat
+			}
+
+		} else {
+
+			BroadErrorMsg("该玩家已加入", ws)
+			lock6.Unlock()
+			return
+
+		}
+
+	}
+	// else {
+	// 	//broadRoomInfo(room, ws)
+	// 	log.Info("加入观战玩家")
+	// 	room.RoomPlayers[player.Uid] = player
+	// 	player.GameRoom = room
+	// 	player.Status = uint32(message.GameStatus_Player_Status_10)
+	// 	room.GzPlayers = append(room.GzPlayers, player)
+	// 	//BroadErrorMsg("人数已满,不能加入", ws)
+	// 	lock6.Unlock()
+	// 	return
+	// }
+
+	//broadInfo(player.GameRoom, int16(message.MSGID_Room_User_Info_Rsp), rData)
+	//广播新玩家加入
+	ClientUserIds[ws] = uid
+	UserClientIds[uid] = ws
+
+	rsp4.PlayerID = player.Uid
+	rsp4.Nick = player.Name
+	rsp4.HeadUrl = player.HeadImg
+
+	rData4, _ := proto.Marshal(rsp4) //回包
+	log.Info("广播玩家加入", rsp4)
+	BroadInfoRoom(player.GameRoom, int16(message.MSGID_Room_Join_User_Rsp), rData4)
+	//如果房间是匹配模式满人则直接开始游戏
+	if player.GameRoom.Mode == ModeMatch {
+
+		if len(room.Players) == room.MaxNum {
+			uid := strconv.Itoa(room.Homeowner)
+			for i := 0; i < len(MatchGameplayers); i++ {
+				if uid == MatchGameplayers[i].Uid {
+					MatchGameplayers[i].Status = uint32(message.GameStatus_Player_Status_2)
+					MatchGameplayers = append(MatchGameplayers[:i], MatchGameplayers[i+1:]...)
+
+					rsp3 := &message.RoomStartGameRsp{}
+					rData3, _ := proto.Marshal(rsp3) //回包
+					log.Info("广播开始玩游戏")
+					BroadInfoRoom(room, int16(message.MSGID_Room_Start_Game_Rsp), rData3)
+					//Utils.ChatRoomBroadcast(room.Id, 2, 1, room.Id)
+					go countdonw2(player, 1)
+					break
+				}
+
+			}
+
+		}
+	}
+	lock6.Unlock()
+}
+
+// 游戏restart 按钮
+func RoomRestartReq(ws *websocket.Conn, data []byte) {
+
+	//req := &message.RoomInfoReq{}
+	player := GamePlayers[ClientUserIds[ws]]
+	// for key, player2 := range player.GameRoom.Players {
+	// 	if player2.Uid == player.Uid {
+	// 		delete(player.GameRoom.Players, key)
+	// 	}
+	// }
+	//delete(player.GameRoom.RoomPlayers, player.Uid)
+	//player.GameRoom = nil
+
+	//log.Info("room====", room.Mode)
+
+	if nil != player {
+		if player.Status !=0 {
+
+			BroadErrorMsg("该玩家已经在匹配或者已开房", ws)
+			return
+		}
+
+	} else {
+		BroadErrorMsg("没有该玩家信息", ws)
+		return
+	}
+
+	if player.Money < player.AdmissionFee {
+		BroadErrorMsg("该玩家入场费不足", ws)
+		return
+	}
+	//Rcfcz(player.Uid, uint32(player.AdmissionFee), 2)
+	lock3.Lock()
+	player.LastHeartbeat=time.Now()
+	//如果是房间内房主开启就拉人
+	if player.Mode == ModeClass {
+		//player.Status2 = uint32(PlayerRooming)
+		//	player.Status = uint32(message.GameStatus_Player_Status_2)
+		room := gameRooms[player.GameRoomId]
+		// if room.RoomType == RoomIn {
+		// 	uid, _ := strconv.Atoi(player.Uid)
+		// 	if room.Homeowner == uid {
+		// 		//如果是房主点的restart 会重新拉人 ,重新加入游戏房间
+		// 		result := Utils.ChatRoomBroadcast(room.ChatRoomId, BroadcastInvisit, room.Id)
+		// 		if result.Code != 200 {
+		// 			log.Printf("发送邀请失败,通知客户端再发起邀请")
+		// 		}
+		// 	}
+
+		// }
+		log.Printf("进入了经典模式")
+		//通知到返回房间信息
+		GamePlayers[ClientUserIds[ws]].Status = 10
+
+		broadRoomInfo(room, ws)
+		var uid = strconv.Itoa(room.Homeowner)
+		if uid != player.Uid {
+			JoinRoom(player.Uid, player.GameRoomId, ws)
+		} else {
+			Rcfcz(player.Uid, uint32(player.AdmissionFee), 2)
+			GamePlayers[ClientUserIds[ws]].Status = 2
+			GamePlayers[ClientUserIds[ws]].GameRoom = room
+			GamePlayers[ClientUserIds[ws]].AdmissionFee = room.AdmissionFee
+			GamePlayers[ClientUserIds[ws]].MaxNum = room.MaxNum
+			GamePlayers[ClientUserIds[ws]].Mode = room.Mode
+			//GamePlayers[ClientUserIds[ws]].Status = uint32(message.GameStatus_Player_Status_2)
+			GamePlayers[ClientUserIds[ws]].FinishNum = 0
+			GamePlayers[ClientUserIds[ws]].Num = 0
+			var rounds = []*GameNumberOfRounds{}
+			var num *GameNumberOfRounds = new(GameNumberOfRounds)
+			var nums = []*uint32{}
+			(*num).Num = 0
+			(*num).NumberOfRounds = nums
+			rounds = append(rounds, num)
+			GamePlayers[ClientUserIds[ws]].NumberOfRounds = rounds
+		}
+		//room := player.GameRoom
+
+	} else if player.Mode == ModeMatch {
+		log.Printf("进入了匹配模式")
+		match(player, ws, int(player.AdmissionFee), player.MaxNum)
+	}
+	lock3.Unlock()
+}
+
+func match(player *GamePlayer, ws *websocket.Conn, adminfee int, playernum int) {
+	// 重新匹配
+	log.Info("进入匹配模式")
+
+	// 判断是否没有玩家已经开房,判断开了房是否能开始游戏
+	lock2.Lock()
+	var roomCreated = false
+	//Rcfcz(player.Uid, uint32(adminfee), 2)
+	for i := 0; i < len(MatchGameplayers); i++ {
+
+		if MatchGameplayers[i].AdmissionFee == uint32(adminfee) && playernum == int(MatchGameplayers[i].MaxNum) {
+			//如果房间满了就开始游戏
+			//player.Status = uint32(message.GameStatus_Player_Status_2)
+			player.Status = uint32(message.GameStatus_Player_Status_1)
+			MatchGameplayers = append(MatchGameplayers, player)
+			//如果匹配金额相同 并且玩家人数相同就进入游戏对战
+			roomCreated = true
+			//移出次玩家
+			room := MatchGameplayers[i].GameRoom
+			player.GameRoom = room
+			room.RoomPlayers[player.Uid] = player
+			//	userRoom[req.Uid] = room
+
+			//匹配成功会加入房间
+
+			if room.Players[0] == nil {
+				player.SeatId = 0
+				room.Players[0] = player
+			} else if room.Players[1] == nil {
+				player.SeatId = 1
+				room.Players[1] = player
+			} else if room.Players[2] == nil {
+				player.SeatId = 2
+				room.Players[2] = player
+			} else if room.Players[3] == nil {
+				player.SeatId = 3
+				room.Players[3] = player
+			}
+			broadRoomInfo(room, ws)
+			//广播新玩家加入
+			rsp4 := &message.RoomJoinUserRsp{}
+			rsp4.PlayerID = player.Uid
+			rsp4.Nick = player.Name
+			rsp4.HeadUrl = player.HeadImg
+			rsp4.SeatID = player.SeatId
+			log.Print("回传数据====", rsp4)
+			rData4, _ := proto.Marshal(rsp4) //回包
+
+			broadInfoExceptUid(room, int16(message.MSGID_Room_Join_User_Rsp), rData4, player.Uid)
+			//BroadInfoRoom(room, int16(message.MSGID_Room_Join_User_Rsp), rData4)
+
+			log.Info("room.MaxNum", room.MaxNum)
+			log.Info("len====", len(room.Players))
+			if len(room.Players) == room.MaxNum {
+				log.Info("开始清除匹配信息")
+				player.GameRoom.ticker.Stop()
+				for _, player := range room.Players {
+					for j := 0; j < len(MatchGameplayers); j++ {
+						if player.Uid == MatchGameplayers[j].Uid {
+							//MatchGameplayers[i].Status = uint32(message.GameStatus_Player_Status_2)
+							MatchGameplayers = append(MatchGameplayers[:j], MatchGameplayers[j+1:]...)
+						}
+					}
+
+				}
+
+				time.Sleep(2 * time.Second)
+				for _, v := range player.GameRoom.Players {
+					v.Status=14
+			//	for i := 0; i < len(player.GameRoom.GzPlayers); i++ {
+				// 		if player.GameRoom.GzPlayers[i].Uid == v.Uid {
+				// 			player.GameRoom.GzPlayers = append(player.GameRoom.GzPlayers[:i], player.GameRoom.GzPlayers[i+1:]...)
+				// 			//MatchGameplayers = append(MatchGameplayers[:j], MatchGameplayers[j+1:]...)
+				// 		}
+				// 	}
+				 }
+				rsp3 := &message.RoomStartGameRsp{}
+				rData3, _ := proto.Marshal(rsp3) //回包
+				log.Info("广播开始玩游戏")
+				room.StartPlayerNum = len(room.Players)
+				go countdonw2(player, 2)
+				BroadInfo(room, int16(message.MSGID_Room_Start_Game_Rsp), rData3)
+				result := Utils.ChatRoomBroadcast(player.GameRoom.ChatRoomId, BroadcastInvisit, player.GameRoom.Id)
+				if result.Code != 200 {
+					log.Printf("通知语聊房开始游戏失败")
+				}
+
+			}
+			break
+
+		}
+	}
+	log.Info("roomCreated====", roomCreated)
+	if !roomCreated {
+		//如果没有匹配到房间就自己开房
+		// result := rcfcz(player.Uid, uint32(adminfee), Reduce)
+		// if result != 200 {
+		// 	BroadErrorMsg("入场费不足,不能进入房间", ws)
+		// 	lock2.Unlock()
+		// 	return
+		// }
+		//userRoom[req.Uid] = idleRoom
+		player.Status = uint32(message.GameStatus_Player_Status_1)
+		MatchGameplayers = append(MatchGameplayers, player)
+		//player.GameRoom.Players = append(player.GameRoom.Players, player)
+		room := GetIdleRoom(uint32(adminfee), playernum, ModeMatch)
+		player.SeatId = 0
+		room.RoomType = RoomOut
+		player.GameRoom = room
+		//	uuid, _ := strconv.Atoi(player.Uid)
+		//room.RoomPlayers=append(room.RoomPlayers,player)
+		room.RoomPlayers[player.Uid] = player
+		//room.Homeowner = uuid
+		//idleRoom.Players = append(idleRoom.Players, player)
+		if room.Players[0] == nil {
+			room.Players[0] = player
+		} else if room.Players[1] == nil {
+			room.Players[1] = player
+		} else if room.Players[2] == nil {
+			room.Players[2] = player
+		} else if room.Players[3] == nil {
+			room.Players[3] = player
+		}
+		// rsp3 := &message.MatchRsp{}
+		// var success uint32 = 0
+		// rsp3.Result = &success
+		// rData3, _ := proto.Marshal(rsp3) //回包
+		// log.Info("广播开始匹配")
+		// //BroadInfo(room, int16(message.MSGID_Match_Rsp), rData3)
+		// sendData(ws, int16(message.MSGID_Match_Rsp), rData3)
+		// broadRoomInfo(room, ws)
+		// rsp3 := &message.CreateGameRsp{}
+		// var rid uint32 = uint32(room.Id)
+		// rsp3.RoomId = &rid
+		// rData3, _ := proto.Marshal(rsp3) //回包
+		// sendData(ws, int16(message.MSGID_Create_Game_Rsp), rData3)
+		broadRoomInfo(room, ws)
+
+		go countdonw3(player.Uid, uint32(room.Id))
+	}
+	// 15046  149946
+	lock2.Unlock()
+}
+
+// 查看房间信息
+func RoomInfoReq(ws *websocket.Conn, data []byte) {
+	req := &message.RoomInfoReq{}
+
+	proto.Unmarshal(data, req) //解包
+	log.Printf("roomId====", req)
+	var room = gameRooms[int(*req.RoomId)]
+	if room == nil {
+		BroadErrorMsg("没有该房间信息", ws)
+		return
+	}
+	if room.Status == 1 {
+		BroadErrorMsg("该房间还不能使用", ws)
+		return
+	}
+	// //回传玩家信息
+	var player = GamePlayers[req.Uid]
+	if player == nil {
+		log.Printf("建立了新玩家")
+		player = createPlayer2(req.Uid, ws,"","",0)
+		if nil == player {
+			//BroadErrorMsg("没有该玩家信息", ws)
+			return
+		}
+	}
+	log.Print("status====", player.Status)
+	if player.Status != 0 && player.Status != 12 {
+		log.Print("status====", player.Status)
+		BroadErrorMsg("该玩家已经加入房间", ws)
+		return
+	}
+	player.GameRoom = room
+	player.Status = 10
+	player.LastHeartbeat=time.Now()
+	log.Print("status2====", player.Status)
+	UserClientIds[player.Uid] = ws
+	ClientUserIds[ws] = player.Uid
+	room.RoomPlayers[player.Uid] = player
+
+	broadRoomInfo(room, ws)
+
+}
+
+func broadRoomInfo(room *GameRoom, ws *websocket.Conn) {
+	//回传玩家信息
+	var uids = []string{}
+	var names = []string{}
+	var headImg = []string{}
+	var moneys = []uint32{}
+	var seatId = []uint32{}
+
+	for i := 0; i < 4; i++ {
+		if room.Players[i] != nil {
+			if room.Players[i].Ticker != nil {
+				//room.Players[i].Ticker.Stop()
+
+			}
+			uids = append(uids, room.Players[i].Uid)
+			names = append(names, room.Players[i].Name)
+			headImg = append(headImg, room.Players[i].HeadImg)
+			moneys = append(moneys, room.Players[i].Money)
+			seatId = append(seatId, uint32(i))
+		}
+
+	}
+	// for _, value := range room.Players {
+
+	// }
+	rsp := &message.RoomInfoRsp{}
+	rsp.Money = moneys
+	rsp.PlayerID = uids
+	rsp.Nick = names
+	rsp.HeadUrl = headImg
+	rsp.SeatId = seatId
+	rsp.AdmissionFee = room.AdmissionFee
+	rsp.PlayerNum = uint32(room.MaxNum)
+	rsp.Mode = uint32(room.Mode)
+	rData, _ := proto.Marshal(rsp) //回包
+	log.Info("回传房间信息", rsp)
+	//MSGID_Room_Info_Rsp
+	sendData(ws, int16(message.MSGID_Room_Info_Rsp), rData)
+}
+
+// 开始游戏通知客户端
+func RoomStartGameReq(ws *websocket.Conn, data []byte) {
+
+	uid := ClientUserIds[ws]
+	player := GamePlayers[uid]
+	if player.GameRoom==nil{
+		BroadErrorMsg("游戏房间没有", ws)
+		return
+	}
+	if len(player.GameRoom.Players) < player.GameRoom.MinNum {
+		BroadErrorMsg("一个人不能游戏", ws)
+		return
+	} else if len(player.GameRoom.Players) > player.GameRoom.MaxNum {
+		BroadErrorMsg("不能超过房间人数", ws)
+		return
+	} else {
+		player.LastHeartbeat=time.Now()
+		req := &message.RoomStartGameRsp{}
+		rData, _ := proto.Marshal(req) //回包
+		log.Info("广播开始玩游戏", player.GameRoom.Players)
+		player.GameRoom.StartPlayerNum = len(player.GameRoom.Players)
+		for _, v := range player.GameRoom.Players {
+			v.Status=14
+	//	for i := 0; i < len(player.GameRoom.GzPlayers); i++ {
+		// 		if player.GameRoom.GzPlayers[i].Uid == v.Uid {
+		// 			player.GameRoom.GzPlayers = append(player.GameRoom.GzPlayers[:i], player.GameRoom.GzPlayers[i+1:]...)
+		// 			//MatchGameplayers = append(MatchGameplayers[:j], MatchGameplayers[j+1:]...)
+		// 		}
+		// 	}
+		 }
+		go countdonw2(player, 3)
+		
+
+		BroadInfoRoom(player.GameRoom, int16(message.MSGID_Room_Start_Game_Rsp), rData)
+		// result := Utils.ChatRoomBroadcast(player.GameRoom.ChatRoomId, BroadcastInvisit, player.GameRoom.Id)
+		// if result.Code != 200 {
+		// 	log.Printf("通知语聊房开始游戏失败")
+		// }
+
+	}
+
+	//通知到开始游戏  广播游戏客户端
+
+}
+
+func BroadErrorMsg(msg string, ws *websocket.Conn) {
+	rsp := &message.PbErrorRsp{}
+	rsp.MessageData = msg
+	rData, _ := proto.Marshal(rsp) //回包
+	sendData(ws, int16(message.MSGID_Pb_Error_Rsp), rData)
+}
+func DissolveTheGame(ws *websocket.Conn, data []byte) {
+	//房主解散游戏房间
+	//	req := &message.DissolveTheGameReq{}
+	uid := ClientUserIds[ws]
+	player := GamePlayers[uid]
+	if player == nil {
+		BroadErrorMsg("玩家不存在", ws)
+		return
+	}
+	if player.GameRoom == nil {
+		BroadErrorMsg("该房间不存在", ws)
+		return
+	}
+	log.Printf("解散房间", player.GameRoom.RoomType)
+	if player.GameRoom.RoomType == 1 {
+		Dissolve_The_Game(player)
+	}
+
+}
+
+// 游戏匹配
+// 玩家登陆,上传头像金币信息
+var MatchGameplayers = []*GamePlayer{}
+
+var lock2 sync.Mutex
+
+var lock3 sync.Mutex
+var lock5 sync.Mutex
+var lock6 sync.Mutex
+
+// 玩家第一次选择模式
+func CreateGameReq(ws *websocket.Conn, data []byte) {
+	req := &message.CreateGameReq{}
+	proto.Unmarshal(data, req) //解包
+	log.Info("data", req)
+	//player := gamePlayers[clientUserIds[ws]]
+	UserClientIds[req.Uid] = ws
+	ClientUserIds[ws] = req.Uid
+	var player *GamePlayer = GamePlayers[req.Uid]
+	if nil != player {
+		if player.Status != 0 {
+
+			BroadErrorMsg("该玩家已经在匹配或者已开房", ws)
+			return
+		}
+
+	} else {
+		player = createPlayer2(req.Uid, ws,req.HeadImg,req.Name,*req.Money)
+		if nil == player {
+
+				BroadErrorMsg("没有该玩家信息", ws)
+			return
+		}
+	}
+	player.LastHeartbeat=time.Now()
+	player.AdmissionFee = uint32(req.AdmissionFee)
+
+	//  if player.Money < player.AdmissionFee {
+	//  	BroadErrorMsg("该玩家入场费不足", ws)
+	//  	return
+	//  }
+	// Rcfcz(player.Uid, uint32(player.AdmissionFee), 2)
+	player.MaxNum = int(req.PlayerNum)
+	player.Mode = int(req.Mode)
+	if req.Mode == uint32(ModeMatch) {
+		//player.Status2 = uint32(PlayerMatching)
+		match(player, ws, int(req.AdmissionFee), int(req.PlayerNum))
+	} else if req.Mode == uint32(ModeClass) {
+		//选择经典开房模式
+
+		//lock5.Lock()
+
+		room := GetIdleRoom(req.AdmissionFee, int(req.PlayerNum), int(req.Mode))
+
+		//player.GameRoom = room
+		player.Status = 12
+
+		uid, _ := strconv.Atoi(player.Uid)
+		room.Homeowner = uid
+		room.RoomPlayers[player.Uid] = player
+		//player.GameRoom = room
+		rsp3 := &message.CreateGameRsp{}
+		var rid uint32 = uint32(room.Id)
+		rsp3.RoomId = &rid
+		rData3, _ := proto.Marshal(rsp3) //回包
+		//broadInfo(player.GameRoom, int16(message.MSGID_Create_Game_Rsp), rData3)
+		sendData(ws, int16(message.MSGID_Create_Game_Rsp), rData3)
+		room.RoomType = RoomOut
+		//log.Printf("chatRoomId=====", *req.ChatRoomId)
+		if req.ChatRoomId != nil {
+			//
+			//room.Type = 1
+			room.RoomType = RoomIn
+			room.ChatRoomId = int(*req.ChatRoomId)
+			//房间内开房的话,则直接拉人
+			result := Utils.ChatRoomBroadcast(int(*req.ChatRoomId), BroadcastInvisit, room.Id)
+			if result.Code != 200 {
+				log.Printf("发送邀请失败,通知客户端再发起邀请")
+			}
+		} else {
+			room.RoomType = RoomOut
+			//room.Players[0]=player
+		}
+		//lock5.Unlock()
+	}
+
+}
+
+func Rcfcz(uid string, adminfee uint32, Type int) int {
+	// 扣除玩家入场费
+	var userInfos = []UserInfo{}
+	uid2, _ := strconv.Atoi(uid)
+	var userInfo = UserInfo{
+		UserId:    uid2,
+		GoldCoins: int(adminfee),
+		Type:      Type,
+	}
+	userInfos = append(userInfos, userInfo)
+	var userInfoReq = UserInfoReq{GameType: 1, UserWallets: userInfos}
+	jsonData2, _ := json.Marshal(userInfoReq)
+	result := Utils.PostData(jsonData2)
+	return result
+}
+
+//player
+//players map
+
+// 房间踢人
+func RoomKickUserReq(ws *websocket.Conn, data []byte) {
+	req := &message.RoomKickUserReq{}
+	proto.Unmarshal(data, req) //解包
+
+	//uid := clientUserIds[ws]
+	player := GamePlayers[req.Uid]
+	uid1 := ClientUserIds[ws]
+	uid, _ := strconv.Atoi(uid1)
+	if uid != player.GameRoom.Homeowner {
+		log.Printf("房主id", player.GameRoom.Homeowner)
+		log.Printf("uid", uid)
+		BroadErrorMsg("不是房主不能踢人", ws)
+		return
+	}
+
+	for key, value := range player.GameRoom.Players {
+		if value.GameRoom.GameEnd == GameNotStarted {
+			if req.Uid == value.Uid {
+				if player.Status != uint32(message.GameStatus_Player_Status_10) {
+					Rcfcz(player.Uid, player.GameRoom.AdmissionFee, Plus)
+				}
+
+				rsp := &message.RoomKickUserRsp{}
+				rsp.Uid = req.Uid
+				rData3, _ := proto.Marshal(rsp) //回包
+				BroadInfoRoom(player.GameRoom, int16(message.MSGID_Room_Kick_User_Rsp), rData3)
+				//player.GameRoom.Players = append(player.GameRoom.Players[:i], player.GameRoom.Players[i+1:]...)
+				delete(player.GameRoom.Players, key)
+				log.Println("开始踢人,查看剩余房间人数", req.Uid, player.GameRoom.Players)
+				delete(GamePlayers, player.Uid)
+				delete(ClientUserIds, UserClientIds[player.Uid])
+				delete(UserClientIds, player.Uid)
+				break
+			}
+		} else {
+			BroadErrorMsg("游戏已经开始不能踢人", ws)
+			break
+		}
+
+	}
+
+}
+
+// 退出房间或者房主解散房间 或者取消匹配
+func RoomQuitReq(ws *websocket.Conn, data []byte) {
+	req := &message.RoomQuitReq{}
+	proto.Unmarshal(data, req) //解包
+	uid := ClientUserIds[ws]
+	player := GamePlayers[uid]
+	if player == nil {
+		BroadErrorMsg("改玩家已退出", ws)
+		return
+	}
+	QuitRoom(player, ws, 11)
+
+}
+
+// 请求关闭客户端
+func RoomCloseReq(ws *websocket.Conn, data []byte) {
+	req := &message.RoomQuitReq{}
+	proto.Unmarshal(data, req) //解包
+	uid := ClientUserIds[ws]
+	player := GamePlayers[uid]
+	if player == nil {
+		BroadErrorMsg("改玩家已退出", ws)
+		return
+	}
+	QuitRoom(player, ws, 0)
+
+}
+func QuitRoom(player *GamePlayer, ws *websocket.Conn, status uint32) {
+	//log.Info("玩家请求退出房间", player.GameRoom)
+	uuid, _ := strconv.Atoi(player.Uid)
+	if player.Status == 2 {
+		player.Status = 10
+		if player.GameRoom.Homeowner == uuid {
+			//广播退出游戏
+			var key2 int
+			for key, value := range player.GameRoom.Players {
+				if player.Uid == value.Uid {
+					//	player.GameRoom.Players = append(player.GameRoom.Players[:i], player.GameRoom.Players[i+1:]...)
+					key2 = key
+					delete(player.GameRoom.Players, key)
+					break
+				}
+			}
+			//player.GameRoom.PlayerNum = player.GameRoom.PlayerNum - 1
+			Rcfcz(player.Uid, player.GameRoom.AdmissionFee, Plus)
+			rsp := &message.RoomQuitUserRsp{}
+			rsp.Uid = player.Uid
+			rData3, _ := proto.Marshal(rsp) //回包
+			BroadInfoRoom(player.GameRoom, int16(message.MSGID_Room_Quit_Rsp), rData3)
+
+			//player.Status = status
+
+			//如果是房间开房玩家就移交下一个玩家,如果房间内没有玩家就解散房间
+			if len(player.GameRoom.Players) == 0 {
+				//解散房间
+				Dissolve_The_Game(player)
+
+			} else {
+				//if player.GameRoom.Mode == 1 {
+				if key2 == 0 {
+					if player.GameRoom.Players[1] != nil {
+						uid, _ := strconv.Atoi(player.GameRoom.Players[1].Uid)
+						player.GameRoom.Homeowner = uid
+					} else if player.GameRoom.Players[2] != nil {
+						uid, _ := strconv.Atoi(player.GameRoom.Players[2].Uid)
+						player.GameRoom.Homeowner = uid
+					} else if player.GameRoom.Players[3] != nil {
+						uid, _ := strconv.Atoi(player.GameRoom.Players[3].Uid)
+						player.GameRoom.Homeowner = uid
+					}
+				} else if key2 == 1 {
+					if player.GameRoom.Players[2] != nil {
+						uid, _ := strconv.Atoi(player.GameRoom.Players[2].Uid)
+						player.GameRoom.Homeowner = uid
+					} else if player.GameRoom.Players[3] != nil {
+						uid, _ := strconv.Atoi(player.GameRoom.Players[3].Uid)
+						player.GameRoom.Homeowner = uid
+					} else if player.GameRoom.Players[0] != nil {
+						uid, _ := strconv.Atoi(player.GameRoom.Players[0].Uid)
+						player.GameRoom.Homeowner = uid
+					}
+				} else if key2 == 2 {
+					if player.GameRoom.Players[3] != nil {
+						uid, _ := strconv.Atoi(player.GameRoom.Players[3].Uid)
+						player.GameRoom.Homeowner = uid
+					} else if player.GameRoom.Players[0] != nil {
+						uid, _ := strconv.Atoi(player.GameRoom.Players[0].Uid)
+						player.GameRoom.Homeowner = uid
+					} else if player.GameRoom.Players[1] != nil {
+						uid, _ := strconv.Atoi(player.GameRoom.Players[1].Uid)
+						player.GameRoom.Homeowner = uid
+					}
+				} else if key2 == 3 {
+					if player.GameRoom.Players[0] != nil {
+						uid, _ := strconv.Atoi(player.GameRoom.Players[0].Uid)
+						player.GameRoom.Homeowner = uid
+					} else if player.GameRoom.Players[1] != nil {
+						uid, _ := strconv.Atoi(player.GameRoom.Players[1].Uid)
+						player.GameRoom.Homeowner = uid
+					} else if player.GameRoom.Players[2] != nil {
+						uid, _ := strconv.Atoi(player.GameRoom.Players[2].Uid)
+						player.GameRoom.Homeowner = uid
+					}
+				}
+				//player.Status = status
+				uuod := strconv.Itoa(player.GameRoom.Homeowner)
+				log.Print("玩家是否移交房主", player.GameRoom.Mode)
+				if player.GameRoom.Mode == 1 {
+					rsp2 := &message.RoomChangeOfHomeownerRsp{}
+					rsp2.Uid = uuod
+					rData4, _ := proto.Marshal(rsp2) //回包
+					log.Print("广播玩家移交房主", player.GameRoom.Mode)
+					BroadInfoRoom(player.GameRoom, int16(message.MSGID_Room_Change_Of_Homeowner_Rsp), rData4)
+				} else if player.GameRoom.Mode == 2 {
+					for key, value := range player.GameRoom.Players {
+						if uuod == value.Uid {
+							//	player.GameRoom.Players = append(player.GameRoom.Players[:i], player.GameRoom.Players[i+1:]...)
+							player.GameRoom.Players[key].Status = uint32(message.GameStatus_Player_Status_1)
+							MatchGameplayers = append(MatchGameplayers, value)
+							break
+						}
+					}
+				}
+				//player.GameRoom.RoomPlayers
+				//delete(GamePlayers, player.Uid)
+				//delete(ClientUserIds, ws)
+				//delete(UserClientIds, player.Uid)
+				//	}
+			}
+
+		} else {
+			//不是房主的情况下
+			for key, value := range player.GameRoom.Players {
+				if player.Uid == value.Uid {
+					//	player.GameRoom.Players = append(player.GameRoom.Players[:i], player.GameRoom.Players[i+1:]...)
+					delete(player.GameRoom.Players, key)
+					break
+				}
+			}
+			//player.Status = status
+			//player.GameRoom.PlayerNum = player.GameRoom.PlayerNum - 1
+			Rcfcz(player.Uid, player.GameRoom.AdmissionFee, Plus)
+
+			// delete(GamePlayers, player.Uid)
+			// delete(ClientUserIds, ws)
+			// delete(UserClientIds, player.Uid)
+			rsp := &message.RoomQuitUserRsp{}
+			rsp.Uid = player.Uid
+			rData3, _ := proto.Marshal(rsp) //回包
+			BroadInfoRoom(player.GameRoom, int16(message.MSGID_Room_Quit_Rsp), rData3)
+		}
+		//delete(GamePlayers, player.Uid)
+		//delete(ClientUserIds, ws)
+		//log.Printf("有玩家退出了清除了对应的ws", ClientUserIds[ws])
+		//delete(UserClientIds, player.Uid)
+	} else if player.Status == 10 {
+		for i := 0; i < len(player.GameRoom.GzPlayers); i++ {
+			if player.GameRoom.GzPlayers[i].Uid == player.Uid {
+
+				player.GameRoom.GzPlayers = append(player.GameRoom.GzPlayers[:i], player.GameRoom.GzPlayers[i+1:]...)
+
+				i-- // 删除元素后,需要减少索引
+				break
+			}
+		}
+		delete(GamePlayers, player.Uid)
+		delete(ClientUserIds, ws)
+		delete(UserClientIds, player.Uid)
+
+		rsp3 := &message.QuitRsp{}
+		rsp3.SeatID = &player.SeatId
+		rsp3.PlayerStatus = player.Status
+		rsp3.Uid=player.Uid
+		rData4, _ := proto.Marshal(rsp3) //回包
+		BroadInfo(player.GameRoom, int16(message.MSGID_Quit_Rsq), rData4)
+
+		rsp := &message.RoomQuitUserRsp{}
+		rsp.Uid = player.Uid
+		rData3, _ := proto.Marshal(rsp) //回包
+		BroadInfoRoom(player.GameRoom, int16(message.MSGID_Room_Quit_Rsp), rData3)
+
+	} else if player.Status == 1 {
+
+		CancenMatch(player.Uid)
+		
+	
+	} else if player.Status == 11 || player.Status == 12 {
+
+		player.Status = 0
+		delete(GamePlayers, player.Uid)
+		delete(ClientUserIds, ws)
+		delete(UserClientIds, player.Uid)
+	} else if player.Status == 14 {
+
+		Dissolve_The_Game(player)
+	} else {
+		//在游戏里退出直接退出游戏
+		Quit(player.Uid)
+		//delete(ClientUserIds, ws)
+		//delete(UserClientIds, player.Uid)
+	}
+
+}
+
+func Dissolve_The_Game(player *GamePlayer) {
+
+	//广播解散游戏
+	rsp := &message.DissolveTheGameRsp{}
+	//rsp.Uid = req.Uid
+	rData3, _ := proto.Marshal(rsp) //回包
+	if player==nil{
+		
+		return
+	}
+	if player.GameRoom==nil{
+		return
+	}
+	BroadInfoRoom(player.GameRoom, int16(message.MSGID_Dissolve_The_Game_Rsp), rData3)
+	log.Printf("通知解散房间")
+	UpdateRoom(player.GameRoom)
+
+	var userInfos = []UserInfo{}
+	for _, value := range player.GameRoom.Players {
+		uid2, _ := strconv.Atoi(value.Uid)
+		var userInfo = UserInfo{
+			UserId:    uid2,
+			GoldCoins: int(player.GameRoom.AdmissionFee),
+			Type:      Plus,
+		}
+		//delete(userRoom, room.Players[j].Uid)
+		userInfos = append(userInfos, userInfo)
+		delete(GamePlayers, value.Uid)
+		delete(ClientUserIds, UserClientIds[value.Uid])
+		delete(UserClientIds, value.Uid)
+	}
+	for j := 0; j < len(player.GameRoom.GzPlayers); j++ {
+
+		delete(GamePlayers, player.GameRoom.GzPlayers[j].Uid)
+		delete(ClientUserIds, UserClientIds[player.GameRoom.GzPlayers[j].Uid])
+		delete(UserClientIds, player.GameRoom.GzPlayers[j].Uid)
+	}
+	var userInfoReq = UserInfoReq{GameType: 1, UserWallets: userInfos}
+	jsonData2, _ := json.Marshal(userInfoReq)
+	if len(userInfos)>0{
+		Utils.PostData(jsonData2)
+	}
+
+
+	// uid := player.Uid
+	if player != nil {
+		delete(GamePlayers, player.Uid)
+		delete(ClientUserIds, UserClientIds[player.Uid])
+		delete(UserClientIds, player.Uid)
+	}
+
+}
+
+// 取消匹配
+func CancelMatchReq(ws *websocket.Conn, data []byte) {
+	req := &message.CancelMatchReq{}
+	proto.Unmarshal(data, req) //解包
+	uid := ClientUserIds[ws]
+	CancenMatch(uid)
+
+}
+
+func CancenMatch(uid string) {
+	var player = GamePlayers[uid]
+
+	if player != nil {
+		if player.GameRoom.GameEnd != GameNotStarted {
+			//
+			BroadErrorMsg("游戏已开始,不能取消匹配", UserClientIds[uid])
+			return
+		}
+		// 先取消匹配,
+		player.Status = 0
+
+		//匹配状态下取消匹配并且更新房间状态
+		//var key2 int = 0
+		// player.GameRoom.PlayerNum = player.GameRoom.PlayerNum - 1
+		Rcfcz(player.Uid, player.GameRoom.AdmissionFee, Plus)
+		for key, player2 := range player.GameRoom.Players {
+			if player2.Uid == player.Uid {
+				for j := 0; j < len(MatchGameplayers); j++ {
+					if player2.Uid == MatchGameplayers[j].Uid {
+						//MatchGameplayers[i].Status = uint32(message.GameStatus_Player_Status_2)
+						MatchGameplayers = append(MatchGameplayers[:j], MatchGameplayers[j+1:]...)
+					}
+				}
+				delete(player.GameRoom.Players, key)
+				break
+			}
+
+		}
+
+		
+
+		rsp := &message.RoomQuitUserRsp{}
+		rsp.Uid = player.Uid
+		rData3, _ := proto.Marshal(rsp) //回包
+		BroadInfoRoom(player.GameRoom, int16(message.MSGID_Room_Quit_Rsp), rData3)
+
+		//让房主开启匹配
+
+		delete(GamePlayers, player.Uid)
+		delete(ClientUserIds, UserClientIds[uid])
+		delete(UserClientIds, player.Uid)
+
+		if len(player.GameRoom.Players) == 0 {
+			//解散房间
+			log.Info("开始解散房间")
+			player.GameRoom.ticker.Stop()
+			for _, player2 := range player.GameRoom.Players {
+				for j := 0; j < len(MatchGameplayers); j++ {
+					if player2.Uid == MatchGameplayers[j].Uid {
+						//MatchGameplayers[i].Status = uint32(message.GameStatus_Player_Status_2)
+						MatchGameplayers = append(MatchGameplayers[:j], MatchGameplayers[j+1:]...)
+
+					}
+
+				}
+
+			}
+
+			rsp := &message.RoomQuitUserRsp{}
+			rsp.Uid = player.Uid
+			rData3, _ := proto.Marshal(rsp) //回包
+			BroadInfoRoom(player.GameRoom, int16(message.MSGID_Room_Quit_Rsp), rData3)
+			Dissolve_The_Game(player)
+
+		}
+	}
+
+}
+
+// 客户端邀请房间内玩家
+func RoomInviteReq(ws *websocket.Conn, data []byte) {
+	req := &message.RoomInviteReq{}
+
+	proto.Unmarshal(data, req) //解包
+	result2 := Utils.ChatRoomBroadcast(int(*req.ChatRoomId), BroadcastInvisit, int(*req.RoomId))
+	if result2.Code != 200 {
+		log.Printf("发送邀请失败,通知客户端再发起邀请")
+	}
+	rsp := &message.RoomInviteRsp{}
+
+	var result uint32 = 0
+	rsp.Result = &result
+	rData3, _ := proto.Marshal(rsp) //回包
+
+	sendData(ws, int16(message.MSGID_Room_Invite_Rsp), rData3)
+
+}
+
+func DiscReq(ws *websocket.Conn, data []byte) {
+	req := &message.DiscReq{}
+	proto.Unmarshal(data, req) //解包
+	room := gameRooms[int(req.RoomId)]
+	if room.Status == RoomBusy {
+		// if room.GameEnd == 0 {
+
+		// } else if room.GameEnd == 1 {
+
+		// }
+		// rsp := &message.DiscR{}
+		// var game = uint32(room.GameEnd)
+		// rsp.RoomStatus = &game
+		// rData3, _ := proto.Marshal(rsp) //回包
+
+		// sendData(ws, int16(message.MSGID_Disc_Rsp), rData3)
+	}
+}
+
+func SendDataReq(ws *websocket.Conn, data []byte) {
+	req := &message.SendMsgReq{}
+	proto.Unmarshal(data, req) //解包
+	uid := ClientUserIds[ws]
+	var player = GamePlayers[uid]
+	rsp := &message.SendMsgRsp{}
+	rsp.Uid=uid
+	rsp.Data = req.Data
+	
+	rData3, _ := proto.Marshal(rsp) //解包
+	//	room := gameRooms[int(req.RoomId)]
+	//BroadInfo()
+	BroadInfo(player.GameRoom, int16(message.MSGID_Send_Msg_Rsp), rData3)
+	//sendData(ws, int16(message.MSGID_Send_Msg_Rsp), rData3)
+}
+
+func Gettoken(c *gin.Context) SqlResponse {
+	appID := "53c2ddc63bbc41228d916e1bea9a566a"
+	appCertificate := "ccefdf8d574d42a6a042a9415fceb18c"
+	channelName := "1"
+	uid := uint32(1)
+	//uidStr := "2882341273"
+	tokenExpirationInSeconds := uint32(3600)
+	privilegeExpirationInSeconds := uint32(3600)
+	// joinChannelPrivilegeExpireInSeconds := uint32(3600)
+	// pubAudioPrivilegeExpireInSeconds := uint32(3600)
+	// pubVideoPrivilegeExpireInSeconds := uint32(3600)
+	// pubDataStreamPrivilegeExpireInSeconds := uint32(3600)
+
+	result, err := rtctokenbuilder.BuildTokenWithUid(appID, appCertificate, channelName, uid, rtctokenbuilder.RoleSubscriber, tokenExpirationInSeconds, privilegeExpirationInSeconds)
+	if err != nil {
+		fmt.Println(err)
+	} else {
+		fmt.Printf("Token with int uid: %s\n", result)
+	}
+	log.Printf("result==", result)
+	var sql = SqlResponse{
+		Code:    200,
+		Message: "成功",
+		Data:    result,
+	}
+	return sql
+	//c.JSON(http.StatusOK, sql)
+	// result, err = rtctokenbuilder.BuildTokenWithUserAccount(appID, appCertificate, channelName, uidStr, rtctokenbuilder.RoleSubscriber, tokenExpirationInSeconds, privilegeExpirationInSeconds)
+	// if err != nil {
+	// 	fmt.Println(err)
+	// } else {
+	// 	fmt.Printf("Token with user account: %s\n", result)
+	// }
+
+	// result, err1 := rtctokenbuilder.BuildTokenWithUidAndPrivilege(appID, appCertificate, channelName, uid,
+	// 	tokenExpirationInSeconds, joinChannelPrivilegeExpireInSeconds, pubAudioPrivilegeExpireInSeconds, pubVideoPrivilegeExpireInSeconds, pubDataStreamPrivilegeExpireInSeconds)
+	// if err1 != nil {
+	// 	fmt.Println(err1)
+	// } else {
+	// 	fmt.Printf("Token with int uid and privilege: %s\n", result)
+	// }
+
+	// result, err1 = rtctokenbuilder.BuildTokenWithUserAccountAndPrivilege(appID, appCertificate, channelName, uidStr,
+	// 	tokenExpirationInSeconds, joinChannelPrivilegeExpireInSeconds, pubAudioPrivilegeExpireInSeconds, pubVideoPrivilegeExpireInSeconds, pubDataStreamPrivilegeExpireInSeconds)
+
+	// if err1 != nil {
+	// 	fmt.Println(err1)
+	// } else {
+	// 	fmt.Printf("Token with user account and privilege: %s\n", result)
+	// }
+}

+ 901 - 0
Server/GameServer/Server/PlaneGame/Module/Room.go

@@ -0,0 +1,901 @@
+package Module
+
+import (
+	"Server-Core/Server/GameServer/Server/PlaneGame/Utils"
+	util "Server-Core/Server/GameServer/Server/PlaneGame/Utils"
+	message "Server-Core/Server/Message"
+	scheme "Server-Core/Server/Scheme"
+	"encoding/json"
+	"fmt"
+	"math"
+	"sort"
+	"strconv"
+	"sync"
+	"time"
+
+	"github.com/gin-gonic/gin"
+	"github.com/golang/protobuf/proto"
+	log "github.com/sirupsen/logrus"
+	"xorm.io/builder"
+)
+
+const (
+	RoomIdle         int = 1 // 1代表空闲
+	RoomBusy         int = 2 //2代表使用中
+	GameNotStarted   int = 0 //1 未开始
+	GamePlaying      int = 1 // 进行中
+	GameEnd          int = 2 // 已结束
+	ModeClass        int = 1 //经典
+	ModeMatch        int = 2 //匹配
+	Plus             int = 1 //加
+	Reduce           int = 2 //减
+	RoomIn           int = 1 //房间内
+	RoomOut          int = 2 //房间外
+	BroadcastInvisit int = 1 //1.邀请
+	BroadcastStart   int = 2 //2.开始游戏
+	PlayerIdle       int = 1 //1.玩家空闲
+	PlayerMatching   int = 2 //2.玩家在匹配中
+	PlayerRooming    int = 3 //2.玩家在房间内
+)
+
+type GameRoom struct {
+	
+	Id             int                   `xorm:"not null pk autoincr INT(11)" json:"id"`
+	Ds             uint32                 `xorm:"-"`
+	Players        map[int]*GamePlayer      `xorm:"-"`//开始游戏的总人数
+	GzPlayers      []*GamePlayer          `xorm:"-"` //观战玩家人数
+	RoomPlayers    map[string]*GamePlayer    `xorm:"-"`//房间内玩家
+	PlayerNum      int                    `xorm:"INT(11)" ` //加入游戏房间人数
+	StartPlayerNum int                     `xorm:"-"`//开始房间确定的游戏人数
+	RankPlayers    map[int]*GamePlayer     `xorm:"-"`//结算时的游戏排行  //通过指针引用同一个玩家的内存地址,不会开辟新的内存空间
+	RunnerNum      int                     `xorm:"-"`//逃跑人数
+	ArrivalNum     int                     `xorm:"-"`//到达终点人数
+	GameEnd        int                  `xorm:"INT(11)" `  //0未开始,1进行中,2已结束
+	//	TimeOut     int           //房间内操作倒计时
+	ticker       *time.Ticker
+	DataList     []*scheme.SzItem   `xorm:"-"`//读取筛子权重的csv数据
+	Status       int               `xorm:"INT(11)" ` //1代表空闲 2代表使用中
+	MaxNum       int                `xorm:"-"`//最大房间人数
+	AdmissionFee uint32             `xorm:"-"`//入场费
+	MinNum       int               `xorm:"-"`//最小房间人数
+	Type         int               `xorm:"INT(11)" `//1是logo,2 baloot
+
+	Homeowner  int      `xorm:"-"`//房主id
+	Mode       int      `xorm:"INT(11)" ` //游戏模式,1是经典,2是匹配
+	RoomType   int      `xorm:"-"`//1是房间内开启,2是房间外开启
+	ChatRoomId int     `xorm:"-"`//
+	CountDown  int      `xorm:"-"`//结算倒计时
+	Logo       string    `xorm:"VARCHAR(255)"`//结算倒计时 
+}
+type GameRoomVo struct {
+	Id        int    `json:"id"`
+	PlayerNum int    `json:"playerNum"` //加入游戏的人数
+	Status    int    `json:"status"`    //房间状态 0未开始,1进行中,2已结束
+	Logo      string `json:"logo"`      //房间logo
+}
+
+// 根据uid映射对应的房间
+// var userRoom map[string]*GameRoom = make(map[string]*GameRoom)
+var gameRooms map[int]*GameRoom = make(map[int]*GameRoom)
+var DataList []*scheme.SzItem = []*scheme.SzItem{}
+var Maps map[int][]int = make(map[int][]int)
+
+type UserInfoReq struct {
+	GameType    int        `json:"gameType"`    //游戏类型: 1.ludo 2.其他
+	UserWallets []UserInfo `json:"userWallets"` //结算时的游戏排行
+}
+type UserInfo struct {
+	GoldCoins int `json:"goldCoins"` //数量
+	Type      int `json:"type"`      //类型: 1.加 2.减
+	UserId    int `json:"userId"`    // ⽤户ID
+
+}
+type Obj struct {
+	core   int //初始化最小对象数 100
+	Max    int //最大对象数  1000
+	UserId int //扩容阈值  100的倍数
+	//每次扩容数
+	//转对象池阈值
+
+}
+
+func ObjectPool() sync.Pool {
+
+	// 一个[]byte的对象池,每个对象为一个[]byte
+	var roomPool = sync.Pool{
+		New: func() interface{} {
+			b := make(map[int]*GameRoom)
+			return &b
+		},
+	}
+	return roomPool
+}
+
+// 房间id初始化
+func RoomInit(start int, end int) {
+
+	/*	if len(gameRooms)>2000 {
+			var roomPool = sync.Pool{
+			New: func() interface{} {
+				b := make(map[int]*GameRoom)
+				return &b
+			},
+		}
+	}else {*/
+	log.Info("min", len(gameRooms))
+	log.Info("max", len(gameRooms)+100)
+	for i := start; i < end; i++ {
+		//mgr.idGenList[i] = 0 //初始化,全部没有被占用
+		var room = GameRoom{}
+		room.Id = i
+		room.Status = RoomIdle
+		room.PlayerNum = 0
+		//room.DataList = DataList
+		room.RunnerNum = 0
+		room.ArrivalNum = 0
+		room.GameEnd = GameNotStarted
+		//room.Status = Busy
+		gameRooms[i] = &room
+		//roomPool.Put(gameRooms)
+	}
+
+}
+
+func RoomInit2(c *gin.Context) SqlResponse{
+	users := make([]GameRoom,1000)
+	for i := 0; i < 1000; i++ {
+			var room =GameRoom{Logo: "https://vr-1314677574.cos.ap-nanjing.myqcloud.com/icon.png"}
+			users[i] = room
+	}
+
+	affected, err := Engine.Insert(&users)
+	log.Println("aff==",affected)
+	log.Info("errpppp",err)
+	var sqlResponse SqlResponse = SqlResponse{
+		Code:    200,
+		Message: "成功",
+	
+	}
+
+	//c.JSON(http.StatusOK, sqlResponse)
+	return sqlResponse
+}
+
+// 获取空闲房间
+func GetIdleRoom(adminfee uint32, maxnum int, mode int) *GameRoom {
+	lock5.Lock()
+	//var idle = 0
+	var gameRoom *GameRoom
+	for i := 1; i < len(gameRooms); i++ {
+		//mgr.idGenList[i] = 0 //初始化,全部没有被占用
+		if gameRooms[i].Status == RoomIdle {
+			//	idle = idle + 1
+			gameRooms[i].Status = RoomBusy
+
+			//gameRoom = gameRooms[i]
+			gameRooms[i].MinNum = 2
+			gameRooms[i].AdmissionFee = adminfee
+			gameRooms[i].MaxNum = maxnum
+			gameRooms[i].Mode = mode
+			//gameRooms[i].RoomType = true
+			gameRooms[i].DataList = DataList
+			//初始化构建玩家
+			var rankPlayer = map[int]*GamePlayer{}
+			var gzPlayer = []*GamePlayer{}
+			var player = map[int]*GamePlayer{}
+			var roomPlayer = map[string]*GamePlayer{}
+			gameRooms[i].RoomPlayers = roomPlayer
+			gameRooms[i].RankPlayers = rankPlayer
+			gameRooms[i].GzPlayers = gzPlayer
+			gameRooms[i].Players = player
+			gameRooms[i].PlayerNum = 0
+			gameRooms[i].RunnerNum = 0
+			gameRooms[i].ArrivalNum = 0
+			gameRooms[i].GameEnd = GameNotStarted
+
+			gameRoom = gameRooms[i]
+			break
+		}
+	}
+	if gameRoom == nil {
+		RoomInit(len(gameRooms), len(gameRooms)+100)
+		lock5.Unlock()
+		return GetIdleRoom(adminfee, maxnum, mode)
+	}
+	lock5.Unlock()
+	return gameRoom
+	/*if idle == 0 {
+
+	}
+	*/
+}
+func GetIdleRoom2(adminfee uint32, maxnum int, mode int) *GameRoom {
+	lock5.Lock()
+	//var idle = 0
+	var gameRoom GameRoom= GameRoom{Status:1}
+
+	//var gameRoom 
+	has, _ := Engine.Get(&gameRoom)
+	if has{
+		gameRoom.Status = RoomBusy
+
+		//gameRoom = gameRooms[i]
+		gameRoom.MinNum = 2
+		gameRoom.AdmissionFee = adminfee
+		gameRoom.MaxNum = maxnum
+		gameRoom.Mode = mode
+		//gameRooms[i].RoomType = true
+		gameRoom.DataList = DataList
+		//初始化构建玩家
+		var rankPlayer = map[int]*GamePlayer{}
+		var gzPlayer = []*GamePlayer{}
+		var player = map[int]*GamePlayer{}
+		var roomPlayer = map[string]*GamePlayer{}
+		gameRoom.Type=1
+		gameRoom.RoomPlayers = roomPlayer
+		gameRoom.RankPlayers = rankPlayer
+		gameRoom.GzPlayers = gzPlayer
+		gameRoom.Players = player
+		gameRoom.PlayerNum = 0
+		gameRoom.RunnerNum = 0
+		gameRoom.ArrivalNum = 0
+		gameRoom.GameEnd = GameNotStarted
+		Engine.ID(gameRoom.Id).Update(gameRoom)
+	}else {
+		// RoomInit(len(gameRooms), len(gameRooms)+100)
+		// lock5.Unlock()
+		Engine.Insert(&gameRoom)
+		gameRoom.Status = RoomBusy
+
+		//gameRoom = gameRooms[i]
+		gameRoom.MinNum = 2
+		gameRoom.AdmissionFee = adminfee
+		gameRoom.MaxNum = maxnum
+		gameRoom.Mode = mode
+		gameRoom.Type=1
+		//gameRooms[i].RoomType = true
+		gameRoom.DataList = DataList
+		//初始化构建玩家
+		var rankPlayer = map[int]*GamePlayer{}
+		var gzPlayer = []*GamePlayer{}
+		var player = map[int]*GamePlayer{}
+		var roomPlayer = map[string]*GamePlayer{}
+		gameRoom.RoomPlayers = roomPlayer
+		gameRoom.RankPlayers = rankPlayer
+		gameRoom.GzPlayers = gzPlayer
+		gameRoom.Players = player
+		gameRoom.PlayerNum = 0
+		gameRoom.RunnerNum = 0
+		gameRoom.ArrivalNum = 0
+		gameRoom.GameEnd = GameNotStarted
+		Engine.ID(gameRoom.Id).Update(gameRoom)
+	}
+	lock5.Unlock()
+	return &gameRoom
+	/*if idle == 0 {
+
+	}
+	*/
+}
+// 更新房间状态为空闲
+func UpdateRoom(room *GameRoom) {
+	/*	for for i := 0; i < len(players); i++  {
+
+		}
+		gameRooms[id].Players
+		delete(userClientIds, uid)
+		delete(clientUserIds, ws)*/
+	// var room = GameRoom{}
+	// room.Id = id
+	// room.Status = Idle
+	// room.PlayerNum = 0
+	// //room.DataList = DataList
+	// room.RunnerNum = 0
+	// room.ArrivalNum = 0
+	// room.GameEnd = 0
+	// gameRooms[id] = &room
+	if room != nil {
+		if room.ticker!=nil{
+			room.ticker.Stop()
+		}
+		room.Status = RoomIdle
+	}
+
+	// gameRooms[id].Status = Idle
+	// gameRooms[id].PlayerNum = 0
+	// gameRooms[id].Players = nil
+	// gameRooms[id].GameEnd = 0
+	// gameRooms[id].RunnerNum = 0
+	// gameRooms[id].RankPlayers = nil
+	// gameRooms[id].ticker = nil
+	// gameRooms[id].DataList = nil
+	// gameRooms[id].ArrivalNum = 0
+
+	//return nil
+	/*if idle == 0 {
+	}
+	*/
+}
+
+type SqlResponse struct {
+	Code    int         `json:"code"`
+	Message string      `json:"message"`
+	Data    interface{} `json:"data"`
+}
+type ResponseUserData struct {
+	RoomId   string `json:"roomId"`
+	DialogId int    `json:"dialogId"`
+}
+type ResponseUserData2 struct {
+	//RoomId   string `json:"roomId"`
+	DialogId int `json:"dialogId"`
+}
+
+func GameInit(c *gin.Context) SqlResponse {
+	//解析游戏玩家数据
+	//更改游戏玩家数据
+	var reqData RequestUserData
+	if err := c.BindJSON(&reqData); err != nil {
+		log.Info("发生了错误")
+	}
+	//初始化房间地图
+	room := GetIdleRoom(1, 1, 1)
+
+	room.Status = RoomBusy
+	room.DataList = DataList
+	//初始化构建玩家
+	var rankPlayer = map[int]*GamePlayer{}
+	room.RankPlayers = rankPlayer
+	for i := 0; i < len(reqData.Data); i++ {
+		//初始化飞机
+		var plane = []*GamePlane{}
+		for j := 0; j < 4; j++ {
+			gamePlane := createPlane(j, reqData.Data[i].Uid)
+			plane = append(plane, &gamePlane)
+		}
+		gamePlayer := createPlayer(i, plane, reqData.Data, room)
+		if room.Players[i] == nil {
+			room.Players[i] = &gamePlayer
+		}
+		//room.Players = append(room.Players, &gamePlayer)
+		if gamePlayer.GameRoom != nil {
+			var sql = SqlResponse{
+				Code:    666,
+				Message: "有玩家已在游戏房间,不能开始游戏",
+				//Data:    ResponseUserData,
+			}
+			return sql
+			//临时初始化用
+			//delete(userRoom, gamePlayer.Uid)
+		}
+
+		//	userRoom[gamePlayer.Uid] = room
+		log.Info("玩家id", gamePlayer.Uid)
+		go countdonw2(&gamePlayer, 4)
+		//玩家设置倒计时,未连接则解散房间退出游戏 逻辑还未开发
+
+	}
+
+	var ResponseUserData = ResponseUserData{RoomId: strconv.Itoa(int(room.Id))}
+	log.Print("response===", ResponseUserData)
+	var sql = SqlResponse{
+		Code:    200,
+		Message: "成功",
+		Data:    ResponseUserData,
+	}
+	return sql
+
+}
+
+// 热更新筛子csv文件
+func ReloadConfig(c *gin.Context) {
+	sz := util.ReadFile()
+	DataList = sz.DataList
+	//return room.Id
+
+}
+
+func endGame(uid string) {
+
+	log.Info("广播游戏结束")
+
+	//广播结束游戏
+	rsp2 := &message.EndGameRsp{}
+	//	uid := clientUserIds[ws]
+	//结束游戏
+	//log.Printf("uid===", getPlayer(uid))
+	//log.Printf("room", getPlayer(uid).GameRoom)
+	room := getPlayer(uid).GameRoom
+	room.GameEnd = GameEnd
+	room.ticker.Stop()
+	//if room.GameEnd == 1 {
+	/*	if room.ch != nil {
+		close(room.ch)
+		room.wg.Wait()
+
+	}*/
+	var money = []uint32{}
+	var seatIds = []uint32{}
+	var numberOfCollisions = []uint32{}
+	var numberOfHitPieces = []uint32{}
+	var nick = []string{}
+	var moneytotal uint32 = 0
+	for i := len(room.RankPlayers) - 1; i >= 0; i-- {
+		moneytotal = moneytotal + room.AdmissionFee
+	}
+	if room.Mode == ModeClass {
+		var homeownergoin = int(float64(moneytotal) * 0.05)
+		var lastownergoin = uint32(float64(moneytotal) * 0.95)
+		log.Info("排行数据", room.RankPlayers)
+
+		var userInfos = []UserInfo{}
+
+		for i := len(room.RankPlayers) - 1; i >= 0; i-- {
+			//两个人玩的时候直接获胜,没逃跑的第一名,逃跑的第二名
+			//var Type = 1
+			var money1 uint32 = 0
+			if len(room.RankPlayers) < 4 {
+				if i == len(room.RankPlayers)-1 {
+					//小于4个玩家的时候,第一一名玩家会获得除自己外的费用
+					//Type = 1
+					money1 = lastownergoin
+					//不减去入场费
+					money = append(money, lastownergoin)
+				} else {
+
+					//收入为0
+					money = append(money, 0)
+				}
+			} else {
+				if i == len(room.RankPlayers)-1 || i == len(room.RankPlayers)-2 {
+
+					money = append(money, lastownergoin/2)
+					//Type = 1
+					//小于4个玩家的时候,第一和第二名玩家会获得除自己外的费用
+					money1 = lastownergoin / 2
+				} else {
+					money = append(money, 0)
+
+				}
+			}
+			uid2, _ := strconv.Atoi(room.RankPlayers[i].Uid)
+			if money1 > 0 {
+				var userInfo = UserInfo{
+					UserId:    uid2,
+					GoldCoins: int(money1),
+					Type:      Plus,
+				}
+				userInfos = append(userInfos, userInfo)
+			}
+
+			seatIds = append(seatIds, room.RankPlayers[i].SeatId)
+			numberOfCollisions = append(numberOfCollisions, room.RankPlayers[i].Kick)
+			numberOfHitPieces = append(numberOfHitPieces, room.RankPlayers[i].BeKick)
+			nick = append(nick, room.RankPlayers[i].Name)
+		}
+		var userInfo = UserInfo{
+			UserId:    room.Homeowner,
+			GoldCoins: homeownergoin,
+			Type:      Plus,
+		}
+		userInfos = append(userInfos, userInfo)
+
+		var userInfoReq = UserInfoReq{GameType: 1, UserWallets: userInfos}
+		jsonData2, _ := json.Marshal(userInfoReq)
+		Utils.PostData(jsonData2)
+	} else if room.Mode == ModeMatch {
+		//	var homeownergoin = int(float64(moneytotal) * 0.05)
+		//var lastownergoin = uint32(float64(moneytotal) * 0.95)
+		log.Info("排行数据", room.RankPlayers)
+
+		var userInfos = []UserInfo{}
+
+		for i := len(room.RankPlayers) - 1; i >= 0; i-- {
+			//两个人玩的时候直接获胜,没逃跑的第一名,逃跑的第二名
+			//var Type = 0
+			var money1 uint32 = 0
+			if len(room.RankPlayers) < 4 {
+				if i == len(room.RankPlayers)-1 {
+					//小于4个玩家的时候,最后一名玩家会获得除自己外的费用
+					//Type = 1
+					money1 = moneytotal
+					//不减去入场费
+					money = append(money, moneytotal)
+				} else {
+
+					//收入为0
+					money = append(money, 0)
+				}
+			} else {
+				if i == len(room.RankPlayers)-1 || i == len(room.RankPlayers)-2 {
+
+					money = append(money, moneytotal/2)
+					//Type = 1
+					//小于4个玩家的时候,第一和第二名玩家会获得除自己外的费用
+					money1 = moneytotal / 2
+				} else {
+					money = append(money, 0)
+
+				}
+			}
+			uid2, _ := strconv.Atoi(room.RankPlayers[i].Uid)
+			if money1 > 0 {
+				var userInfo = UserInfo{
+					UserId:    uid2,
+					GoldCoins: int(money1),
+					Type:      Plus,
+				}
+				userInfos = append(userInfos, userInfo)
+			}
+
+			seatIds = append(seatIds, room.RankPlayers[i].SeatId)
+			numberOfCollisions = append(numberOfCollisions, room.RankPlayers[i].Kick)
+			numberOfHitPieces = append(numberOfHitPieces, room.RankPlayers[i].BeKick)
+			nick = append(nick, room.RankPlayers[i].Name)
+		}
+
+		var userInfoReq = UserInfoReq{GameType: 1, UserWallets: userInfos}
+		jsonData2, _ := json.Marshal(userInfoReq)
+		Utils.PostData(jsonData2)
+	}
+
+	//Utils.ChatRoomBroadcast(room.Id, 3, 1, room.Id)
+	rsp2.Money = money
+	rsp2.SeatID = seatIds
+	rsp2.Kick = numberOfCollisions
+	rsp2.BeKick = numberOfHitPieces
+	//rsp2.Nick = nick
+	rData2, _ := proto.Marshal(rsp2) //回包
+	room.ticker.Stop()
+	BroadInfo(room, int16(message.MSGID_Eng_Game_Rsp), rData2)
+	log.Info("发送结束数据", rsp2)
+
+	// result := Utils.ChatRoomBroadcast(room.ChatRoomId, BroadcastInvisit, room.Id)
+	// if result.Code != 200 {
+	// 	log.Printf("通知语聊房结束游戏失败")
+	// }
+	for key, _ := range room.Players {
+		//value.Status2 = uint32(PlayerIdle)
+		room.Players[key].Status = 13
+		room.Players[key].FinishNum = 0
+		room.Players[key].Num = 0
+		room.Players[key].Kick = 0
+		room.Players[key].BeKick = 0
+		// if room.Mode == 2 {
+		room.Players[key].GameRoomId = room.Id
+		if room.Mode == ModeMatch {
+			room.Players[key].GameRoom = nil
+
+		}
+
+		// }
+
+		var rounds = []*GameNumberOfRounds{}
+		var num *GameNumberOfRounds = new(GameNumberOfRounds)
+		var nums = []*uint32{}
+		(*num).Num = 0
+		(*num).NumberOfRounds = nums
+		rounds = append(rounds, num)
+		room.Players[key].NumberOfRounds = rounds
+		//gamePlayers[gamePlayer.Uid] = &gamePlayer
+	}
+	for i := 0; i < len(room.GzPlayers); i++ {
+		room.GzPlayers[i].GameRoomId = room.Id
+		room.GzPlayers[i].GameRoom = nil
+		room.GzPlayers[i].Status = uint32(0)
+	}
+	if room.Mode == ModeClass {
+		var rankPlayer = map[int]*GamePlayer{}
+		var gzPlayer = []*GamePlayer{}
+		
+		//var player = map[int]*GamePlayer{}
+		//var roomplayer = map[string]*GamePlayer{}
+		var uid2 = strconv.Itoa(room.Homeowner)
+		//退出房主
+		for key, v := range room.Players {
+			if GamePlayers[v.Uid] != nil {
+				GamePlayers[v.Uid].Status = 0
+			}
+			if v.Uid != uid2 {
+				//除了房主外都会被踢出房间
+				log.Info("踢出玩家", v.Uid)
+				room.Players[key].GameRoom = nil
+				delete(room.Players, key)
+				
+
+			}
+
+		}
+		
+		room.RankPlayers = rankPlayer
+		room.GzPlayers = gzPlayer
+		//room.Players = player
+		room.PlayerNum = 0
+		//room.RoomPlayers = roomplayer
+		room.RunnerNum = 0
+		room.ArrivalNum = 0
+		room.GameEnd = GameNotStarted
+		Engine.ID(room.Id).Update(room)
+	} else if room.Mode == ModeMatch {
+		for _, v := range room.Players {
+
+				if GamePlayers[v.Uid] != nil {
+					GamePlayers[v.Uid].Status = 0
+				}
+		}
+		room.Status = RoomIdle
+		var rankPlayer = map[int]*GamePlayer{}
+		var gzPlayer = []*GamePlayer{}
+		var player = map[int]*GamePlayer{}
+		var roomplayer = map[string]*GamePlayer{}
+		room.RankPlayers = rankPlayer
+		room.GzPlayers = gzPlayer
+		room.Players = player
+		room.PlayerNum = 0
+		room.RunnerNum = 0
+		room.ArrivalNum = 0
+		room.RoomPlayers = roomplayer
+		room.GameEnd = GameNotStarted
+		Engine.ID(room.Id).Update(room)
+	}
+}
+
+ func ClearSocket() {
+
+ 	log.Printf("开启定时清理心跳")
+	ticker2 := time.NewTicker(time.Second * 30)
+ 	defer ticker2.Stop()
+
+ 	for {
+		select {
+			case <-ticker2.C:
+ 				for key, value := range UserClientIds {
+ 					player := getPlayer(key)
+ 					if player != nil {
+						
+ 						seconds := time.Since(player.LastHeartbeat).Seconds() // 返回time1与当前时间的秒级差值
+						
+ 						log.Info("second", seconds)
+ 						if seconds > 20 {
+							log.Println("player.LastHeartbeat",player.LastHeartbeat)
+							log.Println("timenow",time.Now())
+							//清除该用户数据
+							log.Printf("清楚用户数据",player.Uid)
+							
+							QuitRoom(player, value, 0)
+							delete(GamePlayers, player.Uid)
+							if UserClientIds[player.Uid]!=nil{
+								delete(ClientUserIds, UserClientIds[player.Uid])
+								delete(UserClientIds, player.Uid)
+							}
+							
+							
+						
+
+					
+ 							}
+ 						}
+
+ 				}
+
+ 		}
+ 	}
+
+ }
+func Initmap2() {
+	var maps0 = []int{}
+	for i := 1; i <= 57; i++ {
+		maps0 = append(maps0, i)
+	}
+	Maps[0] = maps0
+	maps1 := initmap(14, 51, 1, 12, 58, 63)
+	Maps[1] = maps1
+	maps2 := initmap(27, 51, 1, 25, 64, 69)
+	Maps[2] = maps2
+	maps3 := initmap(40, 51, 1, 38, 70, 75)
+	Maps[3] = maps3
+}
+
+func initmap(i1start int, i1end int, i2start int, i2end int, i3start int, i3end int) []int {
+	//var maps1 = []GameMap{}
+	var maps1 = []int{}
+	//seat1的行走路线
+	for i := i1start; i <= i1end; i++ {
+		maps1 = append(maps1, i)
+	}
+	maps1 = append(maps1, 76)
+	for i := i2start; i <= i2end; i++ {
+		maps1 = append(maps1, i)
+	}
+	for i := i3start; i <= i3end; i++ {
+		maps1 = append(maps1, i)
+	}
+	return maps1
+}
+
+type Page struct {
+	Records []GameRoomVo `json:"records"`
+	Total   int          `json:"total"`
+}
+type gameRoomes []GameRoom
+
+func (rooms gameRoomes) Len() int {
+	return len(rooms)
+}
+
+func (s gameRoomes) Swap(i, j int) {
+	s[i], s[j] = s[j], s[i]
+}
+func (s gameRoomes) Less(i, j int) bool {
+	return s[i].Id < s[j].Id
+}
+
+func GetRoomPage(c *gin.Context) SqlResponse {
+	
+	page := c.Query("page")
+	pageSize := c.Query("pageSize")
+	fmt.Printf("page",page)
+	fmt.Print("pageSize",pageSize)
+	page3, err := strconv.Atoi(page)
+	log.Println(err)
+	pageSize3, _ := strconv.Atoi(pageSize)
+	keys := []GameRoom{}
+
+	for _, value := range gameRooms {
+		if value.Status == RoomBusy && value.Mode == ModeClass {
+			log.Info("房间正在使用中")
+			keys = append(keys, *value)
+		}
+		//log.Print("data", v)
+
+	}
+
+	sort.Sort(gameRoomes(keys))
+	start, end := SlicePage(int64(page3), int64(pageSize3), int64(len(keys))) //第一页1页显示3条数据
+	afterLimitData := keys[start:end]                                         //分页后的数据
+	//fmt.Println("分页后的数据:", afterLimitData[0])
+	fmt.Println("数据总量:", len(keys))
+	var page2 Page
+	page2.Total = len(keys)
+	var gameroomms = []GameRoomVo{}
+	for i := 0; i < len(afterLimitData); i++ {
+		//afterLimitData[i].ticker=nil
+		var gameroomVo = GameRoomVo{}
+		gameroomVo.Id = afterLimitData[i].Id
+		gameroomVo.PlayerNum = afterLimitData[i].PlayerNum + len(afterLimitData[i].GzPlayers)
+		gameroomVo.Status = afterLimitData[i].GameEnd
+		gameroomVo.Logo = "https://vr-1314677574.cos.ap-nanjing.myqcloud.com/icon.png"
+		gameroomms = append(gameroomms, gameroomVo)
+	}
+
+	page2.Records = gameroomms
+	var sqlResponse SqlResponse = SqlResponse{
+		Code:    200,
+		Message: "成功",
+		Data:    page2,
+	}
+
+	//c.JSON(http.StatusOK, sqlResponse)
+	return sqlResponse
+	//return maps1
+}
+func GetRoomPage3(page string,pageSize string) SqlResponse {
+
+	var gameRooms2 =map[int]*GameRoom{}
+
+	gameRooms2[1]=&GameRoom{Status: 2,Mode: 1}
+	//page := c.Query("page")
+	//pageSize := c.Query("pageSize")
+	page3, err := strconv.Atoi(page)
+	log.Println(err)
+	pageSize3, _ := strconv.Atoi(pageSize)
+	keys := []GameRoom{}
+
+	for _, value := range gameRooms2 {
+		if value.Status == RoomBusy && value.Mode == ModeClass {
+			log.Info("房间正在使用中")
+			keys = append(keys, *value)
+		}
+		//log.Print("data", v)
+
+	}
+
+	sort.Sort(gameRoomes(keys))
+	start, end := SlicePage(int64(page3), int64(pageSize3), int64(len(keys))) //第一页1页显示3条数据
+	afterLimitData := keys[start:end]                                         //分页后的数据
+	//fmt.Println("分页后的数据:", afterLimitData[0])
+	
+	var page2 Page
+	page2.Total = len(keys)
+	var gameroomms = []GameRoomVo{}
+	for i := 0; i < len(afterLimitData); i++ {
+		//afterLimitData[i].ticker=nil
+		var gameroomVo = GameRoomVo{}
+		gameroomVo.Id = afterLimitData[i].Id
+		gameroomVo.PlayerNum = afterLimitData[i].PlayerNum + len(afterLimitData[i].GzPlayers)
+		gameroomVo.Status = afterLimitData[i].GameEnd
+		gameroomVo.Logo = "https://vr-1314677574.cos.ap-nanjing.myqcloud.com/icon.png"
+		gameroomms = append(gameroomms, gameroomVo)
+	}
+
+	page2.Records = gameroomms
+	var sqlResponse SqlResponse = SqlResponse{
+		Code:    200,
+		Message: "成功",
+		Data:    page2,
+	}
+	fmt.Println("数据总量:", len(keys),sqlResponse)
+	//c.JSON(http.StatusOK, sqlResponse)
+	return sqlResponse
+	//return maps1
+}
+
+func GetRoomPage2(c *gin.Context) SqlResponse {
+	page2 := c.Query("page")
+	pageSize := c.Query("pageSize")
+	page3, err := strconv.Atoi(page2)
+	log.Println(err)
+	pageSize3, _ := strconv.Atoi(pageSize)
+	log.Println(err)
+
+	var tenusers []GameRoom
+	//i=要取的条数, j=开始的位置
+	Engine.Limit(pageSize3, (page3-1)*pageSize3).Find(&tenusers) //Find only id and name
+	firmware := new(GameRoom)
+	total, err := Engine.Count(firmware)
+	 var page Page
+	 page.Total = int(total)
+	 var gameroomms = []GameRoomVo{}
+	for i := 0; i < len(tenusers); i++ {
+		//afterLimitData[i].ticker=nil
+		var gameroomVo = GameRoomVo{}
+		gameroomVo.Id = tenusers[i].Id
+		gameroomVo.PlayerNum = tenusers[i].PlayerNum + len(tenusers[i].GzPlayers)
+		gameroomVo.Status = tenusers[i].GameEnd
+		gameroomVo.Logo = "https://vr-1314677574.cos.ap-nanjing.myqcloud.com/icon.png"
+		
+		gameroomms = append(gameroomms, gameroomVo)
+	}
+	 page.Records = gameroomms
+	// page.Records = tenusers
+	var sql = SqlResponse{
+		Code:    200,
+		Message: "成功",
+		Data:    page,
+	}
+	//c.JSON(http.StatusOK, sqlResponse)
+	return sql
+	//return maps1
+}
+func SlicePage(page, pageSize, nums int64) (sliceStart, sliceEnd int64) {
+	if page <= 0 {
+		page = 1
+	}
+	if pageSize < 0 {
+		pageSize = 20 //设置一页默认显示的记录数
+	}
+	if pageSize > nums {
+		return 0, nums
+	}
+	// 总页数
+	pageCount := int64(math.Ceil(float64(nums) / float64(pageSize)))
+	if page > pageCount {
+		return 0, 0
+	}
+	sliceStart = (page - 1) * pageSize
+	sliceEnd = sliceStart + pageSize
+
+	if sliceEnd > nums {
+		sliceEnd = nums
+	}
+	return sliceStart, sliceEnd
+}
+func InitRoomDb() () {
+	var rooms []GameRoom
+	Engine.Where(builder.Eq{"status":2}).Find(&rooms)
+   for _,value := range rooms  {
+	value.Status=1
+	//   i.Status=1
+   }
+   Engine.Update(rooms)
+}

+ 10 - 0
Server/GameServer/Server/PlaneGame/Utils/CsvReaderUtil.go

@@ -0,0 +1,10 @@
+package Utils
+
+import scheme "Server-Core/Server/Scheme"
+
+func ReadFile() *scheme.Sz {
+	role := scheme.GetSchemeById(scheme.ID_Sz).(*scheme.Sz)
+	//role.Load()
+	role.LoadData()
+	return role
+}

+ 225 - 0
Server/GameServer/Server/PlaneGame/Utils/HttpUtil.go

@@ -0,0 +1,225 @@
+package Utils
+
+import (
+	base "Server-Core/Server/Base"
+	"crypto/md5"
+	"strconv"
+
+	"bytes"
+	// "strconv"
+	// "crypto/md5"
+	// "encoding/hex"
+	"encoding/hex"
+	"encoding/json"
+	"fmt"
+	"io/ioutil"
+	"log"
+	"net/http"
+
+	//"strconv"
+	"time"
+)
+
+//语聊房的代码能跑就不要动,动了就可能跑不掉
+func PostData(data []byte) int {
+	param := string(data)
+	fmt.Println("data:", param)
+	var key = "dGYGWu5#qaEsQPdD7NnpjD4^BUbF"
+	now := time.Now().UnixNano() / 1e6
+	s3 := fmt.Sprintf("%s%s%s", param, key, strconv.FormatInt(now, 10))
+	fmt.Println("s3",s3)
+	re := md5.Sum([]byte(s3))
+	md5String := hex.EncodeToString(re[:])
+	request, _ := http.NewRequest("POST", "http://47.242.46.203/api/inner/operatingWallet", bytes.NewBuffer(data))
+	request.Header.Set("Content-Type", "application/json; charset=UTF-8")
+	request.Header.Set("sn", md5String)
+	request.Header.Set("t", strconv.FormatInt(now, 10))
+	fmt.Println("sn:", md5String)
+	fmt.Println("t:", now)
+	client := &http.Client{}
+	client.Timeout = 2 * time.Second
+	response, error := client.Do(request)
+	if error != nil {
+		log.Print("扣款失败,该玩家余额不足,不能进行游戏", error)
+		return 666
+	}
+	defer response.Body.Close()
+	fmt.Println("PostData response Status:", response.Status)
+	fmt.Println("response Headers:", response.Header)
+	
+	body, _ := ioutil.ReadAll(response.Body)
+	fmt.Println("response Body:", body)
+	fmt.Println("response Body:", string(body))
+	var UserInfoRsp UserInfoRsp
+
+	json.Unmarshal([]byte(body), &UserInfoRsp)
+
+	if UserInfoRsp.Code != 200 {
+		return 666
+	}
+	log.Print("data222", UserInfoRsp)
+	
+	return UserInfoRsp.Code
+
+	
+}
+
+type UserInfoReq struct {
+	UidSet []int `json:"uidSet"`
+}
+
+type UserInfoRsp struct {
+	Code int               `json:"code"`
+	Msg  string            `json:"msg"`
+	Data []UserInfoDataRsp `json:"data"`
+}
+
+type UserInfoDataRsp struct {
+	UserId    int    `json:"userId"`
+	UserNo    int    `json:"userNo"`
+	NickName  string `json:"nickName"`
+	Avatar    string `json:"avatar"`
+	Gender    int    `json:"gender"`
+	GoldCoins int    `json:"goldCoins"`
+}
+
+func GetUserInfoData(uid int) UserInfoRsp {
+	var userInfoReq = UserInfoReq{}
+	var uidset = []int{}
+	uidset = append(uidset, uid)
+	log.Print("uset=====", uidset)
+	userInfoReq.UidSet = uidset
+	data, _ := json.Marshal(userInfoReq)
+	//request, _ := http.NewRequest("POST", base.Server.Config.BaseURL+"api/inner/listUserBasic", bytes.NewBuffer(data))
+	request, _ := http.NewRequest("POST", "http://47.242.46.203/api/inner/listUserBasic", bytes.NewBuffer(data))
+	request.Header.Set("Content-Type", "application/json; charset=UTF-8")
+	client := &http.Client{}
+	client.Timeout = 2 * time.Second
+	response, error := client.Do(request)
+	if error != nil {
+		//panic(error)
+		log.Printf("获取玩家信息失败查看返回结果", error)
+		var UserInfoRsp = UserInfoRsp{}
+		UserInfoRsp.Code = 666
+		return UserInfoRsp
+		//return nifcloud
+	}
+	defer response.Body.Close()
+	fmt.Println("GetUserInfoData response Status:", response.Status)
+	fmt.Println("response Headers:", response.Header)
+	body, _ := ioutil.ReadAll(response.Body)
+
+	//var articleSlide = map[string]string{}
+	//json.Unmarshal([]byte(body), &SqlResponse)
+	var UserInfoRsp UserInfoRsp
+
+	json.Unmarshal([]byte(body), &UserInfoRsp)
+
+	log.Print("data222", UserInfoRsp)
+	if len(UserInfoRsp.Data) == 0 {
+		UserInfoRsp.Code = 666
+	}
+
+	return UserInfoRsp
+	//log.Print("data2", mapResult["avatar"])
+}
+
+
+
+func GetFbData(uid int,url string,name string, money uint32) UserInfoRsp {
+	var userInfoReq = UserInfoReq{}
+	var uidset = []int{}
+	uidset = append(uidset, uid)
+	log.Print("uset=====", uidset)
+	userInfoReq.UidSet = uidset
+	//data, _ := json.Marshal(userInfoReq)
+	//request, _ := http.NewRequest("POST", base.Server.Config.BaseURL+"api/inner/listUserBasic", bytes.NewBuffer(data))
+	// request, _ := http.NewRequest("POST", "http://47.242.46.203/api/inner/listUserBasic", bytes.NewBuffer(data))
+	// request.Header.Set("Content-Type", "application/json; charset=UTF-8")
+	// client := &http.Client{}
+	// client.Timeout = 2 * time.Second
+	// response, error := client.Do(request)
+	// if error != nil {
+	// 	//panic(error)
+	// 	log.Printf("获取玩家信息失败查看返回结果", error)
+	// 	var UserInfoRsp = UserInfoRsp{}
+	// 	UserInfoRsp.Code = 666
+	// 	return UserInfoRsp
+	// 	//return nifcloud
+	// }
+	// defer response.Body.Close()
+	// fmt.Println("GetUserInfoData response Status:", response.Status)
+	// fmt.Println("response Headers:", response.Header)
+	// body, _ := ioutil.ReadAll(response.Body)
+
+	//var articleSlide = map[string]string{}
+	//json.Unmarshal([]byte(body), &SqlResponse)
+	var data=[]UserInfoDataRsp{}
+	var UserInfoDataRsp =UserInfoDataRsp{}
+	UserInfoDataRsp.GoldCoins=1000000
+	
+	UserInfoDataRsp.UserId=uid
+	UserInfoDataRsp.NickName=name
+	UserInfoDataRsp.Avatar=url
+	//UserInfoDataRsp.GoldCoins=int(money)
+	data = append(data,UserInfoDataRsp )
+	var UserInfoRsp UserInfoRsp=UserInfoRsp{Data: data,Code: 200}
+
+	// json.Unmarshal([]byte(body), &UserInfoRsp)
+
+	// log.Print("data222", UserInfoRsp)
+	// if len(UserInfoRsp.Data) == 0 {
+	// 	UserInfoRsp.Code = 666
+	// }
+
+
+	return UserInfoRsp
+	//log.Print("data2", mapResult["avatar"])
+}
+
+type RoomReq struct {
+	RoomId         int    `json:"roomId"`         //语聊房id
+	BroadcastType  int    `json:"broadcastType"`  //⼴播类型: 1.邀请 2.开始游戏 3.结束游戏
+	GameType       int    `json:"gameType"`       //游戏类型: 1.ludo
+	GameChatRoomId int    `json:"gameChatRoomId"` //游戏房间id
+	GameIcon       string `json:"gameIcon"`       //游戏图片
+	GameName       string `json:"gameName"`       //游戏名称
+}
+
+func ChatRoomBroadcast(roomId int, BroadcastType int, gameChatRoomId int) UserInfoRsp {
+	var RoomReq = RoomReq{}
+	RoomReq.RoomId = roomId
+	RoomReq.BroadcastType = BroadcastType
+	RoomReq.GameType = 1
+	RoomReq.GameChatRoomId = gameChatRoomId
+	RoomReq.GameIcon = "https://vr-1314677574.cos.ap-nanjing.myqcloud.com/icon.png"
+	RoomReq.GameName = "lodo"
+	data, _ := json.Marshal(RoomReq)
+	log.Printf("roomId=====", roomId)
+	log.Printf("gameChatRoomId=====", gameChatRoomId)
+	request, _ := http.NewRequest("POST", base.Server.Config.BaseURL+"api/inner/chatRoomBroadcast", bytes.NewBuffer(data))
+	request.Header.Set("Content-Type", "application/json; charset=UTF-8")
+	client := &http.Client{}
+	client.Timeout = 2 * time.Second
+	response, error := client.Do(request)
+	if error != nil {
+		//	panic(error)
+
+		//panic(error)
+		log.Printf("调用语聊房失败查看返回结果", error)
+		var UserInfoRsp = UserInfoRsp{}
+		UserInfoRsp.Code = 666
+		return UserInfoRsp
+		//return nifcloud
+
+	}
+	defer response.Body.Close()
+	fmt.Println("ChatRoomBroadcast response Status:", response.Status)
+	fmt.Println("response Headers:", response.Header)
+	body, _ := ioutil.ReadAll(response.Body)
+	var UserInfoRsp UserInfoRsp
+	fmt.Println("response Body:", string(body))
+	json.Unmarshal([]byte(body), &UserInfoRsp)
+	return UserInfoRsp
+
+}

+ 118 - 0
Server/GameServer/Server/Server.go

@@ -0,0 +1,118 @@
+package server
+
+import (
+	base "Server-Core/Server/Base"
+	log "Server-Core/Server/Base/Log"
+	db "Server-Core/Server/GameServer/Server/DB"
+	web "Server-Core/Server/GameServer/Server/PlaneGame/GmWeb"
+	module "Server-Core/Server/GameServer/Server/PlaneGame/Module"
+	util "Server-Core/Server/GameServer/Server/PlaneGame/Utils"
+	message "Server-Core/Server/Message"
+	scheme "Server-Core/Server/Scheme"
+	"math/rand"
+	"time"
+
+)
+
+var GServer *GameServer
+
+type GameServer struct {
+}
+
+func (gs *GameServer) Run() {
+
+}
+
+func (gs *GameServer) LogicStart() {
+	log.Info("创建schemeMgr")
+	scheme.Create()
+	log.Info("创建schemeMgr done")
+
+	log.Info("创建logicMgr")
+	//	service.Register("logicMgr", new(logic.LogicMgr))
+	log.Info("logicMgr done")
+
+	log.Info("创建DB连接")
+	config := base.Server.Config
+	dbInit := base.DBInit{
+		Host:     config.DBHost,
+		Port:     config.DBPort,
+		User:     config.DBUser,
+		Password: config.DBPassword,
+		DBName:   config.DBName,
+	}
+	db.Create(&dbInit)
+	log.Info("创建DB连接 done")
+	web.Create(config.GMPort) //Gm接口
+
+	rand.Seed(time.Now().UnixNano())
+	log.Info("初始化web")
+	datainit()
+	go web.Webinit(config.WEBPort)
+	go web.InitSw()
+	go module.ClearSocket()
+
+}
+
+// 数据初始化
+func datainit() {
+	//Module.GameRoom
+	module.RoomInit(0, 100)
+	web.CmdExector[int16(message.MSGID_Get_User_Info_Req)] = module.GetUserInfo
+	//web.CmdExector[int16(message.MSGID_Get_User_Info_Req2)] = module.GetUserInfo2
+	web.CmdExector[int16(message.MSGID_Throw_The_Dice_Req)] = module.ThrowTheDice
+	web.CmdExector[int16(message.MSGID_Move_Req)] = module.Move
+	web.CmdExector[int16(message.MSGID_Start_Plane_Req)] = module.StartFly
+	web.CmdExector[int16(message.MSGID_Trusteeship_Req)] = module.Trusteeship
+	web.CmdExector[int16(message.MSGID_MSGID_Heartbeat_Push)] = module.MyHeartBeatReq
+	web.CmdExector[int16(message.MSGID_Quit_Req)] = module.QuitGame
+	web.CmdExector[int16(message.MSGID_Create_Game_Req)] = module.CreateGameReq
+	web.CmdExector[int16(message.MSGID_Join_Room_Req)] = module.JoinRoomReq
+	web.CmdExector[int16(message.MSGID_Room_Start_Game_Req)] = module.RoomStartGameReq
+	web.CmdExector[int16(message.MSGID_Room_Kick_User_Req)] = module.RoomKickUserReq
+	web.CmdExector[int16(message.MSGID_Room_Quit_Req)] = module.RoomQuitReq
+	web.CmdExector[int16(message.MSGID_Room_Info_Req)] = module.RoomInfoReq
+	web.CmdExector[int16(message.MSGID_Cancel_Match_Req)] = module.CancelMatchReq
+	web.CmdExector[int16(message.MSGID_Room_Invite_Req)] = module.RoomInviteReq
+	web.CmdExector[int16(message.MSGID_Room_Restart_Req)] = module.RoomRestartReq
+	web.CmdExector[int16(message.MSGID_Disc_Req)] = module.DiscReq
+	web.CmdExector[int16(message.MSGID_Dissolve_The_Game_Req)] = module.DissolveTheGame
+	web.CmdExector[int16(message.MSGID_Close_Game_Req)] = module.RoomCloseReq
+	web.CmdExector[int16(message.MSGID_Get_User_Money_Req)] = module.GetUserMoneyReq
+	web.CmdExector[int16(message.MSGID_Send_Msg_Req)] = module.SendDataReq
+	//初始化文件数据
+	sz := util.ReadFile()
+	module.DataList = sz.DataList
+
+	module.Initmap2()
+
+
+
+	//初始化房间数据
+
+}
+
+func (gs *GameServer) LogicStep() {
+
+}
+
+func (gs *GameServer) OnServerReady() {
+	//config := base.Server.Config
+
+	log.Info("创建客户端连接管理")
+	//service.Register("clientMgr", new(client.Mgr), config.ClientPort)
+	log.Info("服务器启动完成")
+	//logic.CreateHighUid(2)
+	/*str, result := Sensitive.GetMap().CheckSensitive("我是习近平的大哥胡锦涛")
+	log.Info("CheckSensitive str:%s result:%t", str, result)
+	target := Sensitive.GetMap().FindAllSensitive("我是习近平的大哥胡锦涛")
+	for key, value := range target {
+		log.Info("CheckSensitive key:%s value:%d", key, value.Indexes)
+	}*/
+
+}
+
+func (gs *GameServer) LogicEnd() {
+	//config := base.Server.Config
+	log.Info("服务器关闭")
+}

+ 4947 - 0
Server/Message/Message.pb.go

@@ -0,0 +1,4947 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// 	protoc-gen-go v1.26.0
+// 	protoc        v4.25.1
+// source: Message.proto
+
+package message
+
+import (
+	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+	reflect "reflect"
+	sync "sync"
+)
+
+const (
+	// Verify that this generated code is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+	// Verify that runtime/protoimpl is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+// 通用操作结果码
+type GameStatus int32
+
+const (
+	GameStatus_GAME_STATUS_OK              GameStatus = 0
+	GameStatus_GAME_STATUS_PLAYER_NIL      GameStatus = 1001 // 玩家不存在
+	GameStatus_GAME_STATUS_UID_PASSWD_NIL  GameStatus = 1002 // 账号或密码不能为空
+	GameStatus_GAME_STATUS_UID_ERROR       GameStatus = 1003 // 账号不存在
+	GameStatus_GAME_STATUS_PASSWD_ERROR    GameStatus = 1004 // 密码错误
+	GameStatus_GAME_STATUS_ROOM_NOT_EXIT   GameStatus = 1005 // 房间不存在
+	GameStatus_GAME_STATUS_PB_ERR          GameStatus = 1006 //协议解析报错
+	GameStatus_GAME_STATUS_INNER_ERR       GameStatus = 1007 // 服务器内部错误
+	GameStatus_GAME_STATUS_LOGIN_CHECK_ERR GameStatus = 1055 // 登录校验失败
+	GameStatus_Player_Status_0             GameStatus = 11   //表示玩家在大厅,
+	GameStatus_Player_Status_1             GameStatus = 1    //表示玩家开始匹配,
+	GameStatus_Player_Status_2             GameStatus = 2    //玩家进入游戏房间,
+	GameStatus_Player_Status_3             GameStatus = 3    //ready,玩家落座开始游戏
+	GameStatus_Player_Status_4             GameStatus = 4    //play,
+	GameStatus_Player_Status_5             GameStatus = 5    //胜利后观战,
+	GameStatus_Player_Status_6             GameStatus = 6    //胜利后离开,
+	GameStatus_Player_Status_7             GameStatus = 7    //组队逃跑,
+	GameStatus_Player_Status_8             GameStatus = 8    //逃跑,
+	GameStatus_Player_Status_9             GameStatus = 9    //托管,
+	GameStatus_Player_Status_10            GameStatus = 10   //观战玩家,
+)
+
+// Enum value maps for GameStatus.
+var (
+	GameStatus_name = map[int32]string{
+		0:    "GAME_STATUS_OK",
+		1001: "GAME_STATUS_PLAYER_NIL",
+		1002: "GAME_STATUS_UID_PASSWD_NIL",
+		1003: "GAME_STATUS_UID_ERROR",
+		1004: "GAME_STATUS_PASSWD_ERROR",
+		1005: "GAME_STATUS_ROOM_NOT_EXIT",
+		1006: "GAME_STATUS_PB_ERR",
+		1007: "GAME_STATUS_INNER_ERR",
+		1055: "GAME_STATUS_LOGIN_CHECK_ERR",
+		11:   "Player_Status_0",
+		1:    "Player_Status_1",
+		2:    "Player_Status_2",
+		3:    "Player_Status_3",
+		4:    "Player_Status_4",
+		5:    "Player_Status_5",
+		6:    "Player_Status_6",
+		7:    "Player_Status_7",
+		8:    "Player_Status_8",
+		9:    "Player_Status_9",
+		10:   "Player_Status_10",
+	}
+	GameStatus_value = map[string]int32{
+		"GAME_STATUS_OK":              0,
+		"GAME_STATUS_PLAYER_NIL":      1001,
+		"GAME_STATUS_UID_PASSWD_NIL":  1002,
+		"GAME_STATUS_UID_ERROR":       1003,
+		"GAME_STATUS_PASSWD_ERROR":    1004,
+		"GAME_STATUS_ROOM_NOT_EXIT":   1005,
+		"GAME_STATUS_PB_ERR":          1006,
+		"GAME_STATUS_INNER_ERR":       1007,
+		"GAME_STATUS_LOGIN_CHECK_ERR": 1055,
+		"Player_Status_0":             11,
+		"Player_Status_1":             1,
+		"Player_Status_2":             2,
+		"Player_Status_3":             3,
+		"Player_Status_4":             4,
+		"Player_Status_5":             5,
+		"Player_Status_6":             6,
+		"Player_Status_7":             7,
+		"Player_Status_8":             8,
+		"Player_Status_9":             9,
+		"Player_Status_10":            10,
+	}
+)
+
+func (x GameStatus) Enum() *GameStatus {
+	p := new(GameStatus)
+	*p = x
+	return p
+}
+
+func (x GameStatus) String() string {
+	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (GameStatus) Descriptor() protoreflect.EnumDescriptor {
+	return file_Message_proto_enumTypes[0].Descriptor()
+}
+
+func (GameStatus) Type() protoreflect.EnumType {
+	return &file_Message_proto_enumTypes[0]
+}
+
+func (x GameStatus) Number() protoreflect.EnumNumber {
+	return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use GameStatus.Descriptor instead.
+func (GameStatus) EnumDescriptor() ([]byte, []int) {
+	return file_Message_proto_rawDescGZIP(), []int{0}
+}
+
+// 踢人原因
+type KickReason int32
+
+const (
+	KickReason_KICK_REASON_UNKNOWN           KickReason = 0
+	KickReason_KICK_REASON_LOGIN_ELSEWHERE   KickReason = 1
+	KickReason_KICK_REASON_HEARTBEAT_TIMEOUT KickReason = 2
+	KickReason_KICK_REASON_NOT_LOGIN         KickReason = 3
+)
+
+// Enum value maps for KickReason.
+var (
+	KickReason_name = map[int32]string{
+		0: "KICK_REASON_UNKNOWN",
+		1: "KICK_REASON_LOGIN_ELSEWHERE",
+		2: "KICK_REASON_HEARTBEAT_TIMEOUT",
+		3: "KICK_REASON_NOT_LOGIN",
+	}
+	KickReason_value = map[string]int32{
+		"KICK_REASON_UNKNOWN":           0,
+		"KICK_REASON_LOGIN_ELSEWHERE":   1,
+		"KICK_REASON_HEARTBEAT_TIMEOUT": 2,
+		"KICK_REASON_NOT_LOGIN":         3,
+	}
+)
+
+func (x KickReason) Enum() *KickReason {
+	p := new(KickReason)
+	*p = x
+	return p
+}
+
+func (x KickReason) String() string {
+	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (KickReason) Descriptor() protoreflect.EnumDescriptor {
+	return file_Message_proto_enumTypes[1].Descriptor()
+}
+
+func (KickReason) Type() protoreflect.EnumType {
+	return &file_Message_proto_enumTypes[1]
+}
+
+func (x KickReason) Number() protoreflect.EnumNumber {
+	return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use KickReason.Descriptor instead.
+func (KickReason) EnumDescriptor() ([]byte, []int) {
+	return file_Message_proto_rawDescGZIP(), []int{1}
+}
+
+// 心跳包C->S, Cmd.MSGID_Heartbeat_Push(心跳包需要保持,不然玩家会被踢下线)
+type HeartbeatPush struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+}
+
+func (x *HeartbeatPush) Reset() {
+	*x = HeartbeatPush{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_Message_proto_msgTypes[0]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *HeartbeatPush) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*HeartbeatPush) ProtoMessage() {}
+
+func (x *HeartbeatPush) ProtoReflect() protoreflect.Message {
+	mi := &file_Message_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use HeartbeatPush.ProtoReflect.Descriptor instead.
+func (*HeartbeatPush) Descriptor() ([]byte, []int) {
+	return file_Message_proto_rawDescGZIP(), []int{0}
+}
+
+// 登录请求 C->S, Cmd.MSGID_Login
+type LoginReq struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Uid    string `protobuf:"bytes,1,opt,name=uid,proto3" json:"uid,omitempty"`       //账号ID
+	PassWd string `protobuf:"bytes,2,opt,name=passWd,proto3" json:"passWd,omitempty"` //密码
+}
+
+func (x *LoginReq) Reset() {
+	*x = LoginReq{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_Message_proto_msgTypes[1]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *LoginReq) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*LoginReq) ProtoMessage() {}
+
+func (x *LoginReq) ProtoReflect() protoreflect.Message {
+	mi := &file_Message_proto_msgTypes[1]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use LoginReq.ProtoReflect.Descriptor instead.
+func (*LoginReq) Descriptor() ([]byte, []int) {
+	return file_Message_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *LoginReq) GetUid() string {
+	if x != nil {
+		return x.Uid
+	}
+	return ""
+}
+
+func (x *LoginReq) GetPassWd() string {
+	if x != nil {
+		return x.PassWd
+	}
+	return ""
+}
+
+// 登录响应 S->C, Cmd.MSGID_Login
+type LoginRsp struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Result   uint32 `protobuf:"varint,1,opt,name=result,proto3" json:"result,omitempty"`     //结果
+	PlayerId int64  `protobuf:"varint,2,opt,name=playerId,proto3" json:"playerId,omitempty"` //玩家ID
+	IsNew    bool   `protobuf:"varint,3,opt,name=isNew,proto3" json:"isNew,omitempty"`       //是否为新玩家
+}
+
+func (x *LoginRsp) Reset() {
+	*x = LoginRsp{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_Message_proto_msgTypes[2]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *LoginRsp) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*LoginRsp) ProtoMessage() {}
+
+func (x *LoginRsp) ProtoReflect() protoreflect.Message {
+	mi := &file_Message_proto_msgTypes[2]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use LoginRsp.ProtoReflect.Descriptor instead.
+func (*LoginRsp) Descriptor() ([]byte, []int) {
+	return file_Message_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *LoginRsp) GetResult() uint32 {
+	if x != nil {
+		return x.Result
+	}
+	return 0
+}
+
+func (x *LoginRsp) GetPlayerId() int64 {
+	if x != nil {
+		return x.PlayerId
+	}
+	return 0
+}
+
+func (x *LoginRsp) GetIsNew() bool {
+	if x != nil {
+		return x.IsNew
+	}
+	return false
+}
+
+type CreateGameReq struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Mode         uint32  `protobuf:"varint,1,opt,name=mode,proto3" json:"mode,omitempty"`                   //游戏模式,1是经典,2是匹配
+	PlayerNum    uint32  `protobuf:"varint,2,opt,name=playerNum,proto3" json:"playerNum,omitempty"`         //选择玩家人数  2是两个人,4是四个人
+	AdmissionFee uint32  `protobuf:"varint,3,opt,name=admissionFee,proto3" json:"admissionFee,omitempty"`   //入场金额   500、1000、2000、5000、10000、20000
+	IsRoom       bool    `protobuf:"varint,4,opt,name=isRoom,proto3" json:"isRoom,omitempty"`               //是否房间内建房
+	Uid          string  `protobuf:"bytes,5,opt,name=uid,proto3" json:"uid,omitempty"`                      //玩家id
+	Name         string  `protobuf:"bytes,6,opt,name=name,proto3" json:"name,omitempty"`                    //玩家名称
+	HeadImg      string  `protobuf:"bytes,7,opt,name=headImg,proto3" json:"headImg,omitempty"`              //玩家头像
+	Money        *uint32 `protobuf:"varint,8,opt,name=money,proto3,oneof" json:"money,omitempty"`           //玩家金币
+	ChatRoomId   *uint32 `protobuf:"varint,9,opt,name=chatRoomId,proto3,oneof" json:"chatRoomId,omitempty"` //语聊房id
+}
+
+func (x *CreateGameReq) Reset() {
+	*x = CreateGameReq{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_Message_proto_msgTypes[3]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *CreateGameReq) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*CreateGameReq) ProtoMessage() {}
+
+func (x *CreateGameReq) ProtoReflect() protoreflect.Message {
+	mi := &file_Message_proto_msgTypes[3]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use CreateGameReq.ProtoReflect.Descriptor instead.
+func (*CreateGameReq) Descriptor() ([]byte, []int) {
+	return file_Message_proto_rawDescGZIP(), []int{3}
+}
+
+func (x *CreateGameReq) GetMode() uint32 {
+	if x != nil {
+		return x.Mode
+	}
+	return 0
+}
+
+func (x *CreateGameReq) GetPlayerNum() uint32 {
+	if x != nil {
+		return x.PlayerNum
+	}
+	return 0
+}
+
+func (x *CreateGameReq) GetAdmissionFee() uint32 {
+	if x != nil {
+		return x.AdmissionFee
+	}
+	return 0
+}
+
+func (x *CreateGameReq) GetIsRoom() bool {
+	if x != nil {
+		return x.IsRoom
+	}
+	return false
+}
+
+func (x *CreateGameReq) GetUid() string {
+	if x != nil {
+		return x.Uid
+	}
+	return ""
+}
+
+func (x *CreateGameReq) GetName() string {
+	if x != nil {
+		return x.Name
+	}
+	return ""
+}
+
+func (x *CreateGameReq) GetHeadImg() string {
+	if x != nil {
+		return x.HeadImg
+	}
+	return ""
+}
+
+func (x *CreateGameReq) GetMoney() uint32 {
+	if x != nil && x.Money != nil {
+		return *x.Money
+	}
+	return 0
+}
+
+func (x *CreateGameReq) GetChatRoomId() uint32 {
+	if x != nil && x.ChatRoomId != nil {
+		return *x.ChatRoomId
+	}
+	return 0
+}
+
+type CreateGameRsp struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	RoomId  *uint32 `protobuf:"varint,1,opt,name=roomId,proto3,oneof" json:"roomId,omitempty"` //房间id
+	Uid     string  `protobuf:"bytes,2,opt,name=uid,proto3" json:"uid,omitempty"`              //用户id
+	Name    string  `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"`            //玩家名称
+	HeadImg string  `protobuf:"bytes,4,opt,name=headImg,proto3" json:"headImg,omitempty"`      //玩家头像
+	Money   *uint32 `protobuf:"varint,5,opt,name=money,proto3,oneof" json:"money,omitempty"`   //玩家金币
+}
+
+func (x *CreateGameRsp) Reset() {
+	*x = CreateGameRsp{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_Message_proto_msgTypes[4]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *CreateGameRsp) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*CreateGameRsp) ProtoMessage() {}
+
+func (x *CreateGameRsp) ProtoReflect() protoreflect.Message {
+	mi := &file_Message_proto_msgTypes[4]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use CreateGameRsp.ProtoReflect.Descriptor instead.
+func (*CreateGameRsp) Descriptor() ([]byte, []int) {
+	return file_Message_proto_rawDescGZIP(), []int{4}
+}
+
+func (x *CreateGameRsp) GetRoomId() uint32 {
+	if x != nil && x.RoomId != nil {
+		return *x.RoomId
+	}
+	return 0
+}
+
+func (x *CreateGameRsp) GetUid() string {
+	if x != nil {
+		return x.Uid
+	}
+	return ""
+}
+
+func (x *CreateGameRsp) GetName() string {
+	if x != nil {
+		return x.Name
+	}
+	return ""
+}
+
+func (x *CreateGameRsp) GetHeadImg() string {
+	if x != nil {
+		return x.HeadImg
+	}
+	return ""
+}
+
+func (x *CreateGameRsp) GetMoney() uint32 {
+	if x != nil && x.Money != nil {
+		return *x.Money
+	}
+	return 0
+}
+
+type RoomInfoRsp struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Result       *uint32  `protobuf:"varint,1,opt,name=result,proto3,oneof" json:"result,omitempty"` //结果
+	Money        []uint32 `protobuf:"varint,2,rep,packed,name=money,proto3" json:"money,omitempty"`
+	PlayerID     []string `protobuf:"bytes,3,rep,name=playerID,proto3" json:"playerID,omitempty"`
+	Nick         []string `protobuf:"bytes,4,rep,name=nick,proto3" json:"nick,omitempty"`                  //昵称
+	HeadUrl      []string `protobuf:"bytes,5,rep,name=headUrl,proto3" json:"headUrl,omitempty"`            //头像
+	SeatId       []uint32 `protobuf:"varint,9,rep,packed,name=seatId,proto3" json:"seatId,omitempty"`      //头像
+	Mode         uint32   `protobuf:"varint,6,opt,name=mode,proto3" json:"mode,omitempty"`                 //游戏模式,1是经典,2是匹配
+	PlayerNum    uint32   `protobuf:"varint,7,opt,name=playerNum,proto3" json:"playerNum,omitempty"`       //选择玩家人数  2是两个人,4是四个人
+	AdmissionFee uint32   `protobuf:"varint,8,opt,name=admissionFee,proto3" json:"admissionFee,omitempty"` //入场金额   500、1000、2000、5000、10000、20000
+}
+
+func (x *RoomInfoRsp) Reset() {
+	*x = RoomInfoRsp{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_Message_proto_msgTypes[5]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *RoomInfoRsp) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*RoomInfoRsp) ProtoMessage() {}
+
+func (x *RoomInfoRsp) ProtoReflect() protoreflect.Message {
+	mi := &file_Message_proto_msgTypes[5]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use RoomInfoRsp.ProtoReflect.Descriptor instead.
+func (*RoomInfoRsp) Descriptor() ([]byte, []int) {
+	return file_Message_proto_rawDescGZIP(), []int{5}
+}
+
+func (x *RoomInfoRsp) GetResult() uint32 {
+	if x != nil && x.Result != nil {
+		return *x.Result
+	}
+	return 0
+}
+
+func (x *RoomInfoRsp) GetMoney() []uint32 {
+	if x != nil {
+		return x.Money
+	}
+	return nil
+}
+
+func (x *RoomInfoRsp) GetPlayerID() []string {
+	if x != nil {
+		return x.PlayerID
+	}
+	return nil
+}
+
+func (x *RoomInfoRsp) GetNick() []string {
+	if x != nil {
+		return x.Nick
+	}
+	return nil
+}
+
+func (x *RoomInfoRsp) GetHeadUrl() []string {
+	if x != nil {
+		return x.HeadUrl
+	}
+	return nil
+}
+
+func (x *RoomInfoRsp) GetSeatId() []uint32 {
+	if x != nil {
+		return x.SeatId
+	}
+	return nil
+}
+
+func (x *RoomInfoRsp) GetMode() uint32 {
+	if x != nil {
+		return x.Mode
+	}
+	return 0
+}
+
+func (x *RoomInfoRsp) GetPlayerNum() uint32 {
+	if x != nil {
+		return x.PlayerNum
+	}
+	return 0
+}
+
+func (x *RoomInfoRsp) GetAdmissionFee() uint32 {
+	if x != nil {
+		return x.AdmissionFee
+	}
+	return 0
+}
+
+type JoinRoomReq struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Uid        string  `protobuf:"bytes,1,opt,name=uid,proto3" json:"uid,omitempty"`                //uID
+	Name       string  `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`              //玩家名称
+	HeadImg    string  `protobuf:"bytes,3,opt,name=headImg,proto3" json:"headImg,omitempty"`        //玩家头像
+	Money      *uint32 `protobuf:"varint,4,opt,name=money,proto3,oneof" json:"money,omitempty"`     //玩家金币
+	RoomId     *uint32 `protobuf:"varint,5,opt,name=roomId,proto3,oneof" json:"roomId,omitempty"`   //房间id
+	RestartBtn bool    `protobuf:"varint,6,opt,name=restartBtn,proto3" json:"restartBtn,omitempty"` //是否是restart点击
+}
+
+func (x *JoinRoomReq) Reset() {
+	*x = JoinRoomReq{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_Message_proto_msgTypes[6]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *JoinRoomReq) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*JoinRoomReq) ProtoMessage() {}
+
+func (x *JoinRoomReq) ProtoReflect() protoreflect.Message {
+	mi := &file_Message_proto_msgTypes[6]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use JoinRoomReq.ProtoReflect.Descriptor instead.
+func (*JoinRoomReq) Descriptor() ([]byte, []int) {
+	return file_Message_proto_rawDescGZIP(), []int{6}
+}
+
+func (x *JoinRoomReq) GetUid() string {
+	if x != nil {
+		return x.Uid
+	}
+	return ""
+}
+
+func (x *JoinRoomReq) GetName() string {
+	if x != nil {
+		return x.Name
+	}
+	return ""
+}
+
+func (x *JoinRoomReq) GetHeadImg() string {
+	if x != nil {
+		return x.HeadImg
+	}
+	return ""
+}
+
+func (x *JoinRoomReq) GetMoney() uint32 {
+	if x != nil && x.Money != nil {
+		return *x.Money
+	}
+	return 0
+}
+
+func (x *JoinRoomReq) GetRoomId() uint32 {
+	if x != nil && x.RoomId != nil {
+		return *x.RoomId
+	}
+	return 0
+}
+
+func (x *JoinRoomReq) GetRestartBtn() bool {
+	if x != nil {
+		return x.RestartBtn
+	}
+	return false
+}
+
+type RoomKickUserReq struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Uid string `protobuf:"bytes,1,opt,name=uid,proto3" json:"uid,omitempty"` //uID
+}
+
+func (x *RoomKickUserReq) Reset() {
+	*x = RoomKickUserReq{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_Message_proto_msgTypes[7]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *RoomKickUserReq) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*RoomKickUserReq) ProtoMessage() {}
+
+func (x *RoomKickUserReq) ProtoReflect() protoreflect.Message {
+	mi := &file_Message_proto_msgTypes[7]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use RoomKickUserReq.ProtoReflect.Descriptor instead.
+func (*RoomKickUserReq) Descriptor() ([]byte, []int) {
+	return file_Message_proto_rawDescGZIP(), []int{7}
+}
+
+func (x *RoomKickUserReq) GetUid() string {
+	if x != nil {
+		return x.Uid
+	}
+	return ""
+}
+
+type RoomKickUserRsp struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Uid  string `protobuf:"bytes,1,opt,name=uid,proto3" json:"uid,omitempty"`   //uID
+	Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` //玩家名称
+}
+
+func (x *RoomKickUserRsp) Reset() {
+	*x = RoomKickUserRsp{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_Message_proto_msgTypes[8]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *RoomKickUserRsp) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*RoomKickUserRsp) ProtoMessage() {}
+
+func (x *RoomKickUserRsp) ProtoReflect() protoreflect.Message {
+	mi := &file_Message_proto_msgTypes[8]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use RoomKickUserRsp.ProtoReflect.Descriptor instead.
+func (*RoomKickUserRsp) Descriptor() ([]byte, []int) {
+	return file_Message_proto_rawDescGZIP(), []int{8}
+}
+
+func (x *RoomKickUserRsp) GetUid() string {
+	if x != nil {
+		return x.Uid
+	}
+	return ""
+}
+
+func (x *RoomKickUserRsp) GetName() string {
+	if x != nil {
+		return x.Name
+	}
+	return ""
+}
+
+type RoomQuitUserReq struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Uid string `protobuf:"bytes,1,opt,name=uid,proto3" json:"uid,omitempty"` //uID
+}
+
+func (x *RoomQuitUserReq) Reset() {
+	*x = RoomQuitUserReq{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_Message_proto_msgTypes[9]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *RoomQuitUserReq) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*RoomQuitUserReq) ProtoMessage() {}
+
+func (x *RoomQuitUserReq) ProtoReflect() protoreflect.Message {
+	mi := &file_Message_proto_msgTypes[9]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use RoomQuitUserReq.ProtoReflect.Descriptor instead.
+func (*RoomQuitUserReq) Descriptor() ([]byte, []int) {
+	return file_Message_proto_rawDescGZIP(), []int{9}
+}
+
+func (x *RoomQuitUserReq) GetUid() string {
+	if x != nil {
+		return x.Uid
+	}
+	return ""
+}
+
+type RoomInviteReq struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Uid        string  `protobuf:"bytes,1,opt,name=uid,proto3" json:"uid,omitempty"`                      //邀请的玩家id
+	ChatRoomId *uint32 `protobuf:"varint,2,opt,name=chatRoomId,proto3,oneof" json:"chatRoomId,omitempty"` //语聊房id
+	RoomId     *uint32 `protobuf:"varint,3,opt,name=roomId,proto3,oneof" json:"roomId,omitempty"`         //游戏房间id
+}
+
+func (x *RoomInviteReq) Reset() {
+	*x = RoomInviteReq{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_Message_proto_msgTypes[10]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *RoomInviteReq) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*RoomInviteReq) ProtoMessage() {}
+
+func (x *RoomInviteReq) ProtoReflect() protoreflect.Message {
+	mi := &file_Message_proto_msgTypes[10]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use RoomInviteReq.ProtoReflect.Descriptor instead.
+func (*RoomInviteReq) Descriptor() ([]byte, []int) {
+	return file_Message_proto_rawDescGZIP(), []int{10}
+}
+
+func (x *RoomInviteReq) GetUid() string {
+	if x != nil {
+		return x.Uid
+	}
+	return ""
+}
+
+func (x *RoomInviteReq) GetChatRoomId() uint32 {
+	if x != nil && x.ChatRoomId != nil {
+		return *x.ChatRoomId
+	}
+	return 0
+}
+
+func (x *RoomInviteReq) GetRoomId() uint32 {
+	if x != nil && x.RoomId != nil {
+		return *x.RoomId
+	}
+	return 0
+}
+
+type RoomInviteRsp struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Result *uint32 `protobuf:"varint,1,opt,name=result,proto3,oneof" json:"result,omitempty"` //结果
+}
+
+func (x *RoomInviteRsp) Reset() {
+	*x = RoomInviteRsp{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_Message_proto_msgTypes[11]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *RoomInviteRsp) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*RoomInviteRsp) ProtoMessage() {}
+
+func (x *RoomInviteRsp) ProtoReflect() protoreflect.Message {
+	mi := &file_Message_proto_msgTypes[11]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use RoomInviteRsp.ProtoReflect.Descriptor instead.
+func (*RoomInviteRsp) Descriptor() ([]byte, []int) {
+	return file_Message_proto_rawDescGZIP(), []int{11}
+}
+
+func (x *RoomInviteRsp) GetResult() uint32 {
+	if x != nil && x.Result != nil {
+		return *x.Result
+	}
+	return 0
+}
+
+type RoomQuitUserRsp struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Uid  string `protobuf:"bytes,1,opt,name=uid,proto3" json:"uid,omitempty"`   //uID
+	Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` //玩家名称
+}
+
+func (x *RoomQuitUserRsp) Reset() {
+	*x = RoomQuitUserRsp{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_Message_proto_msgTypes[12]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *RoomQuitUserRsp) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*RoomQuitUserRsp) ProtoMessage() {}
+
+func (x *RoomQuitUserRsp) ProtoReflect() protoreflect.Message {
+	mi := &file_Message_proto_msgTypes[12]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use RoomQuitUserRsp.ProtoReflect.Descriptor instead.
+func (*RoomQuitUserRsp) Descriptor() ([]byte, []int) {
+	return file_Message_proto_rawDescGZIP(), []int{12}
+}
+
+func (x *RoomQuitUserRsp) GetUid() string {
+	if x != nil {
+		return x.Uid
+	}
+	return ""
+}
+
+func (x *RoomQuitUserRsp) GetName() string {
+	if x != nil {
+		return x.Name
+	}
+	return ""
+}
+
+type JoinRoomInfoRsp struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Result       *uint32 `protobuf:"varint,1,opt,name=result,proto3,oneof" json:"result,omitempty"` //结果
+	Money        string  `protobuf:"bytes,2,opt,name=money,proto3" json:"money,omitempty"`
+	PlayerID     string  `protobuf:"bytes,3,opt,name=playerID,proto3" json:"playerID,omitempty"`
+	PlayerStatus uint32  `protobuf:"varint,4,opt,name=playerStatus,proto3" json:"playerStatus,omitempty"`  // 玩家的当前状态, 0、1 表示空位无玩家,2: sitdown, 3: ready, 4: play, 5: 胜利后观战, 6: 胜利后离开,7: 组队逃跑,8: 逃跑
+	TableID      uint32  `protobuf:"varint,5,opt,name=tableID,proto3" json:"tableID,omitempty"`            // 桌子ID
+	SeatID       *uint32 `protobuf:"varint,6,opt,name=seatID,proto3,oneof" json:"seatID,omitempty"`        //座位号
+	Nick         string  `protobuf:"bytes,7,opt,name=nick,proto3" json:"nick,omitempty"`                   //昵称
+	HeadUrl      string  `protobuf:"bytes,8,opt,name=headUrl,proto3" json:"headUrl,omitempty"`             //头像
+	Gender       string  `protobuf:"bytes,9,opt,name=gender,proto3" json:"gender,omitempty"`               //性别
+	PlayerNum    *uint32 `protobuf:"varint,10,opt,name=playerNum,proto3,oneof" json:"playerNum,omitempty"` // 玩家数量
+	PlayerType   uint32  `protobuf:"varint,11,opt,name=playerType,proto3" json:"playerType,omitempty"`     // 玩家类型1是正常玩家2是机器人
+}
+
+func (x *JoinRoomInfoRsp) Reset() {
+	*x = JoinRoomInfoRsp{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_Message_proto_msgTypes[13]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *JoinRoomInfoRsp) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*JoinRoomInfoRsp) ProtoMessage() {}
+
+func (x *JoinRoomInfoRsp) ProtoReflect() protoreflect.Message {
+	mi := &file_Message_proto_msgTypes[13]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use JoinRoomInfoRsp.ProtoReflect.Descriptor instead.
+func (*JoinRoomInfoRsp) Descriptor() ([]byte, []int) {
+	return file_Message_proto_rawDescGZIP(), []int{13}
+}
+
+func (x *JoinRoomInfoRsp) GetResult() uint32 {
+	if x != nil && x.Result != nil {
+		return *x.Result
+	}
+	return 0
+}
+
+func (x *JoinRoomInfoRsp) GetMoney() string {
+	if x != nil {
+		return x.Money
+	}
+	return ""
+}
+
+func (x *JoinRoomInfoRsp) GetPlayerID() string {
+	if x != nil {
+		return x.PlayerID
+	}
+	return ""
+}
+
+func (x *JoinRoomInfoRsp) GetPlayerStatus() uint32 {
+	if x != nil {
+		return x.PlayerStatus
+	}
+	return 0
+}
+
+func (x *JoinRoomInfoRsp) GetTableID() uint32 {
+	if x != nil {
+		return x.TableID
+	}
+	return 0
+}
+
+func (x *JoinRoomInfoRsp) GetSeatID() uint32 {
+	if x != nil && x.SeatID != nil {
+		return *x.SeatID
+	}
+	return 0
+}
+
+func (x *JoinRoomInfoRsp) GetNick() string {
+	if x != nil {
+		return x.Nick
+	}
+	return ""
+}
+
+func (x *JoinRoomInfoRsp) GetHeadUrl() string {
+	if x != nil {
+		return x.HeadUrl
+	}
+	return ""
+}
+
+func (x *JoinRoomInfoRsp) GetGender() string {
+	if x != nil {
+		return x.Gender
+	}
+	return ""
+}
+
+func (x *JoinRoomInfoRsp) GetPlayerNum() uint32 {
+	if x != nil && x.PlayerNum != nil {
+		return *x.PlayerNum
+	}
+	return 0
+}
+
+func (x *JoinRoomInfoRsp) GetPlayerType() uint32 {
+	if x != nil {
+		return x.PlayerType
+	}
+	return 0
+}
+
+type RoomInfoReq struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	RoomId *uint32 `protobuf:"varint,1,opt,name=roomId,proto3,oneof" json:"roomId,omitempty"` //房间id
+	Uid    string  `protobuf:"bytes,2,opt,name=uid,proto3" json:"uid,omitempty"`              //玩家id
+}
+
+func (x *RoomInfoReq) Reset() {
+	*x = RoomInfoReq{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_Message_proto_msgTypes[14]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *RoomInfoReq) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*RoomInfoReq) ProtoMessage() {}
+
+func (x *RoomInfoReq) ProtoReflect() protoreflect.Message {
+	mi := &file_Message_proto_msgTypes[14]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use RoomInfoReq.ProtoReflect.Descriptor instead.
+func (*RoomInfoReq) Descriptor() ([]byte, []int) {
+	return file_Message_proto_rawDescGZIP(), []int{14}
+}
+
+func (x *RoomInfoReq) GetRoomId() uint32 {
+	if x != nil && x.RoomId != nil {
+		return *x.RoomId
+	}
+	return 0
+}
+
+func (x *RoomInfoReq) GetUid() string {
+	if x != nil {
+		return x.Uid
+	}
+	return ""
+}
+
+type CancelMatchReq struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+}
+
+func (x *CancelMatchReq) Reset() {
+	*x = CancelMatchReq{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_Message_proto_msgTypes[15]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *CancelMatchReq) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*CancelMatchReq) ProtoMessage() {}
+
+func (x *CancelMatchReq) ProtoReflect() protoreflect.Message {
+	mi := &file_Message_proto_msgTypes[15]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use CancelMatchReq.ProtoReflect.Descriptor instead.
+func (*CancelMatchReq) Descriptor() ([]byte, []int) {
+	return file_Message_proto_rawDescGZIP(), []int{15}
+}
+
+type CancelMatchRsp struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Result *uint32 `protobuf:"varint,1,opt,name=result,proto3,oneof" json:"result,omitempty"` //结果0表示成功,其他表示失败
+	Uid    string  `protobuf:"bytes,2,opt,name=uid,proto3" json:"uid,omitempty"`              //用户id
+}
+
+func (x *CancelMatchRsp) Reset() {
+	*x = CancelMatchRsp{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_Message_proto_msgTypes[16]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *CancelMatchRsp) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*CancelMatchRsp) ProtoMessage() {}
+
+func (x *CancelMatchRsp) ProtoReflect() protoreflect.Message {
+	mi := &file_Message_proto_msgTypes[16]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use CancelMatchRsp.ProtoReflect.Descriptor instead.
+func (*CancelMatchRsp) Descriptor() ([]byte, []int) {
+	return file_Message_proto_rawDescGZIP(), []int{16}
+}
+
+func (x *CancelMatchRsp) GetResult() uint32 {
+	if x != nil && x.Result != nil {
+		return *x.Result
+	}
+	return 0
+}
+
+func (x *CancelMatchRsp) GetUid() string {
+	if x != nil {
+		return x.Uid
+	}
+	return ""
+}
+
+type MatchRsp struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Result *uint32 `protobuf:"varint,1,opt,name=result,proto3,oneof" json:"result,omitempty"` //结果  0表示成功,其他表示失败
+}
+
+func (x *MatchRsp) Reset() {
+	*x = MatchRsp{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_Message_proto_msgTypes[17]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *MatchRsp) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*MatchRsp) ProtoMessage() {}
+
+func (x *MatchRsp) ProtoReflect() protoreflect.Message {
+	mi := &file_Message_proto_msgTypes[17]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use MatchRsp.ProtoReflect.Descriptor instead.
+func (*MatchRsp) Descriptor() ([]byte, []int) {
+	return file_Message_proto_rawDescGZIP(), []int{17}
+}
+
+func (x *MatchRsp) GetResult() uint32 {
+	if x != nil && x.Result != nil {
+		return *x.Result
+	}
+	return 0
+}
+
+type MatchJoinUserRsp struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Result    *uint32 `protobuf:"varint,1,opt,name=result,proto3,oneof" json:"result,omitempty"` //结果
+	PlayerID  string  `protobuf:"bytes,2,opt,name=playerID,proto3" json:"playerID,omitempty"`
+	Nick      string  `protobuf:"bytes,3,opt,name=nick,proto3" json:"nick,omitempty"`            //昵称
+	HeadUrl   string  `protobuf:"bytes,4,opt,name=headUrl,proto3" json:"headUrl,omitempty"`      //头像
+	Gender    string  `protobuf:"bytes,5,opt,name=gender,proto3" json:"gender,omitempty"`        //性别
+	PlayerNum uint32  `protobuf:"varint,6,opt,name=playerNum,proto3" json:"playerNum,omitempty"` // 玩家数量
+}
+
+func (x *MatchJoinUserRsp) Reset() {
+	*x = MatchJoinUserRsp{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_Message_proto_msgTypes[18]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *MatchJoinUserRsp) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*MatchJoinUserRsp) ProtoMessage() {}
+
+func (x *MatchJoinUserRsp) ProtoReflect() protoreflect.Message {
+	mi := &file_Message_proto_msgTypes[18]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use MatchJoinUserRsp.ProtoReflect.Descriptor instead.
+func (*MatchJoinUserRsp) Descriptor() ([]byte, []int) {
+	return file_Message_proto_rawDescGZIP(), []int{18}
+}
+
+func (x *MatchJoinUserRsp) GetResult() uint32 {
+	if x != nil && x.Result != nil {
+		return *x.Result
+	}
+	return 0
+}
+
+func (x *MatchJoinUserRsp) GetPlayerID() string {
+	if x != nil {
+		return x.PlayerID
+	}
+	return ""
+}
+
+func (x *MatchJoinUserRsp) GetNick() string {
+	if x != nil {
+		return x.Nick
+	}
+	return ""
+}
+
+func (x *MatchJoinUserRsp) GetHeadUrl() string {
+	if x != nil {
+		return x.HeadUrl
+	}
+	return ""
+}
+
+func (x *MatchJoinUserRsp) GetGender() string {
+	if x != nil {
+		return x.Gender
+	}
+	return ""
+}
+
+func (x *MatchJoinUserRsp) GetPlayerNum() uint32 {
+	if x != nil {
+		return x.PlayerNum
+	}
+	return 0
+}
+
+type RoomStartGameReq struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+}
+
+func (x *RoomStartGameReq) Reset() {
+	*x = RoomStartGameReq{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_Message_proto_msgTypes[19]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *RoomStartGameReq) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*RoomStartGameReq) ProtoMessage() {}
+
+func (x *RoomStartGameReq) ProtoReflect() protoreflect.Message {
+	mi := &file_Message_proto_msgTypes[19]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use RoomStartGameReq.ProtoReflect.Descriptor instead.
+func (*RoomStartGameReq) Descriptor() ([]byte, []int) {
+	return file_Message_proto_rawDescGZIP(), []int{19}
+}
+
+type RoomStartGameRsp struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+}
+
+func (x *RoomStartGameRsp) Reset() {
+	*x = RoomStartGameRsp{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_Message_proto_msgTypes[20]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *RoomStartGameRsp) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*RoomStartGameRsp) ProtoMessage() {}
+
+func (x *RoomStartGameRsp) ProtoReflect() protoreflect.Message {
+	mi := &file_Message_proto_msgTypes[20]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use RoomStartGameRsp.ProtoReflect.Descriptor instead.
+func (*RoomStartGameRsp) Descriptor() ([]byte, []int) {
+	return file_Message_proto_rawDescGZIP(), []int{20}
+}
+
+// 获取玩家数据
+type GetUserInfoReq struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Uid    string `protobuf:"bytes,1,opt,name=uid,proto3" json:"uid,omitempty"`        //账号ID
+	RoomId uint32 `protobuf:"varint,2,opt,name=roomId,proto3" json:"roomId,omitempty"` //房间ID
+}
+
+func (x *GetUserInfoReq) Reset() {
+	*x = GetUserInfoReq{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_Message_proto_msgTypes[21]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GetUserInfoReq) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetUserInfoReq) ProtoMessage() {}
+
+func (x *GetUserInfoReq) ProtoReflect() protoreflect.Message {
+	mi := &file_Message_proto_msgTypes[21]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GetUserInfoReq.ProtoReflect.Descriptor instead.
+func (*GetUserInfoReq) Descriptor() ([]byte, []int) {
+	return file_Message_proto_rawDescGZIP(), []int{21}
+}
+
+func (x *GetUserInfoReq) GetUid() string {
+	if x != nil {
+		return x.Uid
+	}
+	return ""
+}
+
+func (x *GetUserInfoReq) GetRoomId() uint32 {
+	if x != nil {
+		return x.RoomId
+	}
+	return 0
+}
+
+// 获取玩家数据
+type KickUserReq struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Uid string `protobuf:"bytes,1,opt,name=uid,proto3" json:"uid,omitempty"` //账号ID
+}
+
+func (x *KickUserReq) Reset() {
+	*x = KickUserReq{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_Message_proto_msgTypes[22]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *KickUserReq) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*KickUserReq) ProtoMessage() {}
+
+func (x *KickUserReq) ProtoReflect() protoreflect.Message {
+	mi := &file_Message_proto_msgTypes[22]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use KickUserReq.ProtoReflect.Descriptor instead.
+func (*KickUserReq) Descriptor() ([]byte, []int) {
+	return file_Message_proto_rawDescGZIP(), []int{22}
+}
+
+func (x *KickUserReq) GetUid() string {
+	if x != nil {
+		return x.Uid
+	}
+	return ""
+}
+
+type GetUserInfoRsp struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Result          *uint32  `protobuf:"varint,1,opt,name=result,proto3,oneof" json:"result,omitempty"` //结果
+	Money           []string `protobuf:"bytes,2,rep,name=money,proto3" json:"money,omitempty"`
+	PlayerID        []string `protobuf:"bytes,3,rep,name=playerID,proto3" json:"playerID,omitempty"`
+	PlayerStatus    []uint32 `protobuf:"varint,4,rep,packed,name=playerStatus,proto3" json:"playerStatus,omitempty"`       // 玩家的当前状态, 0、1 表示空位无玩家,2: sitdown, 3: ready, 4: play, 5: 胜利后观战, 6: 胜利后离开,7: 组队逃跑,8: 逃跑
+	TableID         []uint32 `protobuf:"varint,5,rep,packed,name=tableID,proto3" json:"tableID,omitempty"`                 // 桌子ID
+	SeatID          []uint32 `protobuf:"varint,6,rep,packed,name=seatID,proto3" json:"seatID,omitempty"`                   //座位号
+	Nick            []string `protobuf:"bytes,7,rep,name=nick,proto3" json:"nick,omitempty"`                               //昵称
+	HeadUrl         []string `protobuf:"bytes,8,rep,name=headUrl,proto3" json:"headUrl,omitempty"`                         //头像
+	Gender          []string `protobuf:"bytes,9,rep,name=gender,proto3" json:"gender,omitempty"`                           //性别
+	PlayerNum       uint32   `protobuf:"varint,10,opt,name=playerNum,proto3" json:"playerNum,omitempty"`                   // 玩家数量
+	PlayerType      []uint32 `protobuf:"varint,11,rep,packed,name=playerType,proto3" json:"playerType,omitempty"`          // 玩家类型1是正常玩家2是机器人
+	SelfSeatId      *uint32  `protobuf:"varint,12,opt,name=selfSeatId,proto3,oneof" json:"selfSeatId,omitempty"`           // 玩家座位号
+	WatchingPlayers *uint32  `protobuf:"varint,13,opt,name=watchingPlayers,proto3,oneof" json:"watchingPlayers,omitempty"` // 观战玩家数量
+	Countdown       *uint32  `protobuf:"varint,14,opt,name=countdown,proto3,oneof" json:"countdown,omitempty"`             // 游戏结束倒计时
+	GameType        uint32   `protobuf:"varint,15,opt,name=gameType,proto3" json:"gameType,omitempty"`                     // 游戏类型,1经典,2匹配
+}
+
+func (x *GetUserInfoRsp) Reset() {
+	*x = GetUserInfoRsp{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_Message_proto_msgTypes[23]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GetUserInfoRsp) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetUserInfoRsp) ProtoMessage() {}
+
+func (x *GetUserInfoRsp) ProtoReflect() protoreflect.Message {
+	mi := &file_Message_proto_msgTypes[23]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GetUserInfoRsp.ProtoReflect.Descriptor instead.
+func (*GetUserInfoRsp) Descriptor() ([]byte, []int) {
+	return file_Message_proto_rawDescGZIP(), []int{23}
+}
+
+func (x *GetUserInfoRsp) GetResult() uint32 {
+	if x != nil && x.Result != nil {
+		return *x.Result
+	}
+	return 0
+}
+
+func (x *GetUserInfoRsp) GetMoney() []string {
+	if x != nil {
+		return x.Money
+	}
+	return nil
+}
+
+func (x *GetUserInfoRsp) GetPlayerID() []string {
+	if x != nil {
+		return x.PlayerID
+	}
+	return nil
+}
+
+func (x *GetUserInfoRsp) GetPlayerStatus() []uint32 {
+	if x != nil {
+		return x.PlayerStatus
+	}
+	return nil
+}
+
+func (x *GetUserInfoRsp) GetTableID() []uint32 {
+	if x != nil {
+		return x.TableID
+	}
+	return nil
+}
+
+func (x *GetUserInfoRsp) GetSeatID() []uint32 {
+	if x != nil {
+		return x.SeatID
+	}
+	return nil
+}
+
+func (x *GetUserInfoRsp) GetNick() []string {
+	if x != nil {
+		return x.Nick
+	}
+	return nil
+}
+
+func (x *GetUserInfoRsp) GetHeadUrl() []string {
+	if x != nil {
+		return x.HeadUrl
+	}
+	return nil
+}
+
+func (x *GetUserInfoRsp) GetGender() []string {
+	if x != nil {
+		return x.Gender
+	}
+	return nil
+}
+
+func (x *GetUserInfoRsp) GetPlayerNum() uint32 {
+	if x != nil {
+		return x.PlayerNum
+	}
+	return 0
+}
+
+func (x *GetUserInfoRsp) GetPlayerType() []uint32 {
+	if x != nil {
+		return x.PlayerType
+	}
+	return nil
+}
+
+func (x *GetUserInfoRsp) GetSelfSeatId() uint32 {
+	if x != nil && x.SelfSeatId != nil {
+		return *x.SelfSeatId
+	}
+	return 0
+}
+
+func (x *GetUserInfoRsp) GetWatchingPlayers() uint32 {
+	if x != nil && x.WatchingPlayers != nil {
+		return *x.WatchingPlayers
+	}
+	return 0
+}
+
+func (x *GetUserInfoRsp) GetCountdown() uint32 {
+	if x != nil && x.Countdown != nil {
+		return *x.Countdown
+	}
+	return 0
+}
+
+func (x *GetUserInfoRsp) GetGameType() uint32 {
+	if x != nil {
+		return x.GameType
+	}
+	return 0
+}
+
+type TKickEventRsp struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	PlayerNum  *uint32          `protobuf:"varint,1,opt,name=PlayerNum,proto3,oneof" json:"PlayerNum,omitempty"` // 被踢玩家数
+	KickPlayer []*KickPlayerRsp `protobuf:"bytes,2,rep,name=kickPlayer,proto3" json:"kickPlayer,omitempty"`
+}
+
+func (x *TKickEventRsp) Reset() {
+	*x = TKickEventRsp{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_Message_proto_msgTypes[24]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *TKickEventRsp) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*TKickEventRsp) ProtoMessage() {}
+
+func (x *TKickEventRsp) ProtoReflect() protoreflect.Message {
+	mi := &file_Message_proto_msgTypes[24]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use TKickEventRsp.ProtoReflect.Descriptor instead.
+func (*TKickEventRsp) Descriptor() ([]byte, []int) {
+	return file_Message_proto_rawDescGZIP(), []int{24}
+}
+
+func (x *TKickEventRsp) GetPlayerNum() uint32 {
+	if x != nil && x.PlayerNum != nil {
+		return *x.PlayerNum
+	}
+	return 0
+}
+
+func (x *TKickEventRsp) GetKickPlayer() []*KickPlayerRsp {
+	if x != nil {
+		return x.KickPlayer
+	}
+	return nil
+}
+
+type KickPlayerRsp struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	SeatId   *uint32 `protobuf:"varint,1,opt,name=seatId,proto3,oneof" json:"seatId,omitempty"`     // 被踢玩家
+	PlaneNum *uint32 `protobuf:"varint,2,opt,name=planeNum,proto3,oneof" json:"planeNum,omitempty"` // 被踢飞机数
+	PlaneID  string  `protobuf:"bytes,3,opt,name=planeID,proto3" json:"planeID,omitempty"`          // 飞机ID
+}
+
+func (x *KickPlayerRsp) Reset() {
+	*x = KickPlayerRsp{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_Message_proto_msgTypes[25]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *KickPlayerRsp) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*KickPlayerRsp) ProtoMessage() {}
+
+func (x *KickPlayerRsp) ProtoReflect() protoreflect.Message {
+	mi := &file_Message_proto_msgTypes[25]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use KickPlayerRsp.ProtoReflect.Descriptor instead.
+func (*KickPlayerRsp) Descriptor() ([]byte, []int) {
+	return file_Message_proto_rawDescGZIP(), []int{25}
+}
+
+func (x *KickPlayerRsp) GetSeatId() uint32 {
+	if x != nil && x.SeatId != nil {
+		return *x.SeatId
+	}
+	return 0
+}
+
+func (x *KickPlayerRsp) GetPlaneNum() uint32 {
+	if x != nil && x.PlaneNum != nil {
+		return *x.PlaneNum
+	}
+	return 0
+}
+
+func (x *KickPlayerRsp) GetPlaneID() string {
+	if x != nil {
+		return x.PlaneID
+	}
+	return ""
+}
+
+type FinishEventRsp struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	SeatId  *uint32 `protobuf:"varint,1,opt,name=seatId,proto3,oneof" json:"seatId,omitempty"` // 到达玩家
+	PlaneId string  `protobuf:"bytes,2,opt,name=planeId,proto3" json:"planeId,omitempty"`      // 飞机ID
+}
+
+func (x *FinishEventRsp) Reset() {
+	*x = FinishEventRsp{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_Message_proto_msgTypes[26]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *FinishEventRsp) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*FinishEventRsp) ProtoMessage() {}
+
+func (x *FinishEventRsp) ProtoReflect() protoreflect.Message {
+	mi := &file_Message_proto_msgTypes[26]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use FinishEventRsp.ProtoReflect.Descriptor instead.
+func (*FinishEventRsp) Descriptor() ([]byte, []int) {
+	return file_Message_proto_rawDescGZIP(), []int{26}
+}
+
+func (x *FinishEventRsp) GetSeatId() uint32 {
+	if x != nil && x.SeatId != nil {
+		return *x.SeatId
+	}
+	return 0
+}
+
+func (x *FinishEventRsp) GetPlaneId() string {
+	if x != nil {
+		return x.PlaneId
+	}
+	return ""
+}
+
+type PlayerRsp struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	SeatId *uint32     `protobuf:"varint,1,opt,name=seatId,proto3,oneof" json:"seatId,omitempty"` // 到达玩家
+	Planes []*PlaneRsp `protobuf:"bytes,2,rep,name=planes,proto3" json:"planes,omitempty"`        // 飞机
+}
+
+func (x *PlayerRsp) Reset() {
+	*x = PlayerRsp{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_Message_proto_msgTypes[27]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *PlayerRsp) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*PlayerRsp) ProtoMessage() {}
+
+func (x *PlayerRsp) ProtoReflect() protoreflect.Message {
+	mi := &file_Message_proto_msgTypes[27]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use PlayerRsp.ProtoReflect.Descriptor instead.
+func (*PlayerRsp) Descriptor() ([]byte, []int) {
+	return file_Message_proto_rawDescGZIP(), []int{27}
+}
+
+func (x *PlayerRsp) GetSeatId() uint32 {
+	if x != nil && x.SeatId != nil {
+		return *x.SeatId
+	}
+	return 0
+}
+
+func (x *PlayerRsp) GetPlanes() []*PlaneRsp {
+	if x != nil {
+		return x.Planes
+	}
+	return nil
+}
+
+type PlaneRsp struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	PlaneId      string  `protobuf:"bytes,1,opt,name=planeId,proto3" json:"planeId,omitempty"`                  // 飞机ID
+	CurrentIndex *uint32 `protobuf:"varint,2,opt,name=currentIndex,proto3,oneof" json:"currentIndex,omitempty"` // 飞机下标
+	PlaneStatus  *uint32 `protobuf:"varint,3,opt,name=planeStatus,proto3,oneof" json:"planeStatus,omitempty"`   // 0是未起飞,1是移动中,2是到达终点
+}
+
+func (x *PlaneRsp) Reset() {
+	*x = PlaneRsp{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_Message_proto_msgTypes[28]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *PlaneRsp) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*PlaneRsp) ProtoMessage() {}
+
+func (x *PlaneRsp) ProtoReflect() protoreflect.Message {
+	mi := &file_Message_proto_msgTypes[28]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use PlaneRsp.ProtoReflect.Descriptor instead.
+func (*PlaneRsp) Descriptor() ([]byte, []int) {
+	return file_Message_proto_rawDescGZIP(), []int{28}
+}
+
+func (x *PlaneRsp) GetPlaneId() string {
+	if x != nil {
+		return x.PlaneId
+	}
+	return ""
+}
+
+func (x *PlaneRsp) GetCurrentIndex() uint32 {
+	if x != nil && x.CurrentIndex != nil {
+		return *x.CurrentIndex
+	}
+	return 0
+}
+
+func (x *PlaneRsp) GetPlaneStatus() uint32 {
+	if x != nil && x.PlaneStatus != nil {
+		return *x.PlaneStatus
+	}
+	return 0
+}
+
+type RoomDjsRsp struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Time *uint32 `protobuf:"varint,1,opt,name=time,proto3,oneof" json:"time,omitempty"` // 倒计时时间
+}
+
+func (x *RoomDjsRsp) Reset() {
+	*x = RoomDjsRsp{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_Message_proto_msgTypes[29]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *RoomDjsRsp) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*RoomDjsRsp) ProtoMessage() {}
+
+func (x *RoomDjsRsp) ProtoReflect() protoreflect.Message {
+	mi := &file_Message_proto_msgTypes[29]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use RoomDjsRsp.ProtoReflect.Descriptor instead.
+func (*RoomDjsRsp) Descriptor() ([]byte, []int) {
+	return file_Message_proto_rawDescGZIP(), []int{29}
+}
+
+func (x *RoomDjsRsp) GetTime() uint32 {
+	if x != nil && x.Time != nil {
+		return *x.Time
+	}
+	return 0
+}
+
+// 加入房间通知其他玩家
+type RoomJoinUserRsp struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Result       *uint32 `protobuf:"varint,1,opt,name=result,proto3,oneof" json:"result,omitempty"` //结果
+	Money        string  `protobuf:"bytes,2,opt,name=money,proto3" json:"money,omitempty"`
+	PlayerID     string  `protobuf:"bytes,3,opt,name=playerID,proto3" json:"playerID,omitempty"`
+	PlayerStatus uint32  `protobuf:"varint,4,opt,name=playerStatus,proto3" json:"playerStatus,omitempty"` // 玩家的当前状态, 0、1 表示空位无玩家,2: sitdown, 3: ready, 4: play, 5: 胜利后观战, 6: 胜利后离开,7: 组队逃跑,8: 逃跑
+	TableID      uint32  `protobuf:"varint,5,opt,name=tableID,proto3" json:"tableID,omitempty"`           // 桌子ID
+	SeatID       uint32  `protobuf:"varint,6,opt,name=seatID,proto3" json:"seatID,omitempty"`             //座位号
+	Nick         string  `protobuf:"bytes,7,opt,name=nick,proto3" json:"nick,omitempty"`                  //昵称
+	HeadUrl      string  `protobuf:"bytes,8,opt,name=headUrl,proto3" json:"headUrl,omitempty"`            //头像
+	Gender       string  `protobuf:"bytes,9,opt,name=gender,proto3" json:"gender,omitempty"`              //性别
+	PlayerNum    uint32  `protobuf:"varint,10,opt,name=playerNum,proto3" json:"playerNum,omitempty"`      // 玩家数量
+	PlayerType   uint32  `protobuf:"varint,11,opt,name=playerType,proto3" json:"playerType,omitempty"`    // 玩家类型1是正常玩家2是机器人
+}
+
+func (x *RoomJoinUserRsp) Reset() {
+	*x = RoomJoinUserRsp{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_Message_proto_msgTypes[30]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *RoomJoinUserRsp) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*RoomJoinUserRsp) ProtoMessage() {}
+
+func (x *RoomJoinUserRsp) ProtoReflect() protoreflect.Message {
+	mi := &file_Message_proto_msgTypes[30]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use RoomJoinUserRsp.ProtoReflect.Descriptor instead.
+func (*RoomJoinUserRsp) Descriptor() ([]byte, []int) {
+	return file_Message_proto_rawDescGZIP(), []int{30}
+}
+
+func (x *RoomJoinUserRsp) GetResult() uint32 {
+	if x != nil && x.Result != nil {
+		return *x.Result
+	}
+	return 0
+}
+
+func (x *RoomJoinUserRsp) GetMoney() string {
+	if x != nil {
+		return x.Money
+	}
+	return ""
+}
+
+func (x *RoomJoinUserRsp) GetPlayerID() string {
+	if x != nil {
+		return x.PlayerID
+	}
+	return ""
+}
+
+func (x *RoomJoinUserRsp) GetPlayerStatus() uint32 {
+	if x != nil {
+		return x.PlayerStatus
+	}
+	return 0
+}
+
+func (x *RoomJoinUserRsp) GetTableID() uint32 {
+	if x != nil {
+		return x.TableID
+	}
+	return 0
+}
+
+func (x *RoomJoinUserRsp) GetSeatID() uint32 {
+	if x != nil {
+		return x.SeatID
+	}
+	return 0
+}
+
+func (x *RoomJoinUserRsp) GetNick() string {
+	if x != nil {
+		return x.Nick
+	}
+	return ""
+}
+
+func (x *RoomJoinUserRsp) GetHeadUrl() string {
+	if x != nil {
+		return x.HeadUrl
+	}
+	return ""
+}
+
+func (x *RoomJoinUserRsp) GetGender() string {
+	if x != nil {
+		return x.Gender
+	}
+	return ""
+}
+
+func (x *RoomJoinUserRsp) GetPlayerNum() uint32 {
+	if x != nil {
+		return x.PlayerNum
+	}
+	return 0
+}
+
+func (x *RoomJoinUserRsp) GetPlayerType() uint32 {
+	if x != nil {
+		return x.PlayerType
+	}
+	return 0
+}
+
+// 1,通知开始掷子并且开始倒计时
+type GameStartRsp struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Result     *uint32 `protobuf:"varint,1,opt,name=result,proto3,oneof" json:"result,omitempty"`         //结果
+	SeatID     *uint32 `protobuf:"varint,2,opt,name=seatID,proto3,oneof" json:"seatID,omitempty"`         //掷子玩家座位号
+	CastSecond *uint32 `protobuf:"varint,3,opt,name=castSecond,proto3,oneof" json:"castSecond,omitempty"` //结果
+}
+
+func (x *GameStartRsp) Reset() {
+	*x = GameStartRsp{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_Message_proto_msgTypes[31]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GameStartRsp) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GameStartRsp) ProtoMessage() {}
+
+func (x *GameStartRsp) ProtoReflect() protoreflect.Message {
+	mi := &file_Message_proto_msgTypes[31]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GameStartRsp.ProtoReflect.Descriptor instead.
+func (*GameStartRsp) Descriptor() ([]byte, []int) {
+	return file_Message_proto_rawDescGZIP(), []int{31}
+}
+
+func (x *GameStartRsp) GetResult() uint32 {
+	if x != nil && x.Result != nil {
+		return *x.Result
+	}
+	return 0
+}
+
+func (x *GameStartRsp) GetSeatID() uint32 {
+	if x != nil && x.SeatID != nil {
+		return *x.SeatID
+	}
+	return 0
+}
+
+func (x *GameStartRsp) GetCastSecond() uint32 {
+	if x != nil && x.CastSecond != nil {
+		return *x.CastSecond
+	}
+	return 0
+}
+
+// 2,客户端请求掷子,空消息
+type ThrowTheDiceReq struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+}
+
+func (x *ThrowTheDiceReq) Reset() {
+	*x = ThrowTheDiceReq{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_Message_proto_msgTypes[32]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ThrowTheDiceReq) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ThrowTheDiceReq) ProtoMessage() {}
+
+func (x *ThrowTheDiceReq) ProtoReflect() protoreflect.Message {
+	mi := &file_Message_proto_msgTypes[32]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ThrowTheDiceReq.ProtoReflect.Descriptor instead.
+func (*ThrowTheDiceReq) Descriptor() ([]byte, []int) {
+	return file_Message_proto_rawDescGZIP(), []int{32}
+}
+
+// 3,通知掷子结果
+type ThrowTheDiceRsp struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Result     *uint32      `protobuf:"varint,1,opt,name=result,proto3,oneof" json:"result,omitempty"`         //结果 0表示成功,其他表示失败
+	SeatID     *uint32      `protobuf:"varint,2,opt,name=seatID,proto3,oneof" json:"seatID,omitempty"`         //座位id
+	Point      uint32       `protobuf:"varint,3,opt,name=point,proto3" json:"point,omitempty"`                 //掷子点数
+	SkipReason *uint32      `protobuf:"varint,4,opt,name=skipReason,proto3,oneof" json:"skipReason,omitempty"` //玩家是否可以行棋,不为0表示不能行棋
+	NextTurn   *uint32      `protobuf:"varint,5,opt,name=nextTurn,proto3,oneof" json:"nextTurn,omitempty"`     //玩家不能行走时下一玩家
+	AutoMove   *uint32      `protobuf:"varint,6,opt,name=autoMove,proto3,oneof" json:"autoMove,omitempty"`     //1代表正常 2自动骰子 3自动起飞,4自动行走
+	Players    []*PlayerRsp `protobuf:"bytes,7,rep,name=players,proto3" json:"players,omitempty"`
+}
+
+func (x *ThrowTheDiceRsp) Reset() {
+	*x = ThrowTheDiceRsp{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_Message_proto_msgTypes[33]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ThrowTheDiceRsp) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ThrowTheDiceRsp) ProtoMessage() {}
+
+func (x *ThrowTheDiceRsp) ProtoReflect() protoreflect.Message {
+	mi := &file_Message_proto_msgTypes[33]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ThrowTheDiceRsp.ProtoReflect.Descriptor instead.
+func (*ThrowTheDiceRsp) Descriptor() ([]byte, []int) {
+	return file_Message_proto_rawDescGZIP(), []int{33}
+}
+
+func (x *ThrowTheDiceRsp) GetResult() uint32 {
+	if x != nil && x.Result != nil {
+		return *x.Result
+	}
+	return 0
+}
+
+func (x *ThrowTheDiceRsp) GetSeatID() uint32 {
+	if x != nil && x.SeatID != nil {
+		return *x.SeatID
+	}
+	return 0
+}
+
+func (x *ThrowTheDiceRsp) GetPoint() uint32 {
+	if x != nil {
+		return x.Point
+	}
+	return 0
+}
+
+func (x *ThrowTheDiceRsp) GetSkipReason() uint32 {
+	if x != nil && x.SkipReason != nil {
+		return *x.SkipReason
+	}
+	return 0
+}
+
+func (x *ThrowTheDiceRsp) GetNextTurn() uint32 {
+	if x != nil && x.NextTurn != nil {
+		return *x.NextTurn
+	}
+	return 0
+}
+
+func (x *ThrowTheDiceRsp) GetAutoMove() uint32 {
+	if x != nil && x.AutoMove != nil {
+		return *x.AutoMove
+	}
+	return 0
+}
+
+func (x *ThrowTheDiceRsp) GetPlayers() []*PlayerRsp {
+	if x != nil {
+		return x.Players
+	}
+	return nil
+}
+
+// 4,客户端请求起飞
+type PlaneStartReq struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	PlaneID string `protobuf:"bytes,1,opt,name=planeID,proto3" json:"planeID,omitempty"` //飞机id,从0开始
+}
+
+func (x *PlaneStartReq) Reset() {
+	*x = PlaneStartReq{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_Message_proto_msgTypes[34]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *PlaneStartReq) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*PlaneStartReq) ProtoMessage() {}
+
+func (x *PlaneStartReq) ProtoReflect() protoreflect.Message {
+	mi := &file_Message_proto_msgTypes[34]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use PlaneStartReq.ProtoReflect.Descriptor instead.
+func (*PlaneStartReq) Descriptor() ([]byte, []int) {
+	return file_Message_proto_rawDescGZIP(), []int{34}
+}
+
+func (x *PlaneStartReq) GetPlaneID() string {
+	if x != nil {
+		return x.PlaneID
+	}
+	return ""
+}
+
+// 5,通知起飞结果
+type PlaneStartRsp struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Result    *uint32      `protobuf:"varint,1,opt,name=result,proto3,oneof" json:"result,omitempty"`     //结果
+	SeatID    *uint32      `protobuf:"varint,2,opt,name=seatID,proto3,oneof" json:"seatID,omitempty"`     //起飞玩家座位id
+	PlaneID   string       `protobuf:"bytes,3,opt,name=planeID,proto3" json:"planeID,omitempty"`          //起飞飞机ID
+	NextTurn  *uint32      `protobuf:"varint,4,opt,name=nextTurn,proto3,oneof" json:"nextTurn,omitempty"` //下一个玩家座位id
+	PlayerNum uint32       `protobuf:"varint,5,opt,name=playerNum,proto3" json:"playerNum,omitempty"`     //玩家数
+	Players   []*PlayerRsp `protobuf:"bytes,6,rep,name=players,proto3" json:"players,omitempty"`
+}
+
+func (x *PlaneStartRsp) Reset() {
+	*x = PlaneStartRsp{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_Message_proto_msgTypes[35]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *PlaneStartRsp) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*PlaneStartRsp) ProtoMessage() {}
+
+func (x *PlaneStartRsp) ProtoReflect() protoreflect.Message {
+	mi := &file_Message_proto_msgTypes[35]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use PlaneStartRsp.ProtoReflect.Descriptor instead.
+func (*PlaneStartRsp) Descriptor() ([]byte, []int) {
+	return file_Message_proto_rawDescGZIP(), []int{35}
+}
+
+func (x *PlaneStartRsp) GetResult() uint32 {
+	if x != nil && x.Result != nil {
+		return *x.Result
+	}
+	return 0
+}
+
+func (x *PlaneStartRsp) GetSeatID() uint32 {
+	if x != nil && x.SeatID != nil {
+		return *x.SeatID
+	}
+	return 0
+}
+
+func (x *PlaneStartRsp) GetPlaneID() string {
+	if x != nil {
+		return x.PlaneID
+	}
+	return ""
+}
+
+func (x *PlaneStartRsp) GetNextTurn() uint32 {
+	if x != nil && x.NextTurn != nil {
+		return *x.NextTurn
+	}
+	return 0
+}
+
+func (x *PlaneStartRsp) GetPlayerNum() uint32 {
+	if x != nil {
+		return x.PlayerNum
+	}
+	return 0
+}
+
+func (x *PlaneStartRsp) GetPlayers() []*PlayerRsp {
+	if x != nil {
+		return x.Players
+	}
+	return nil
+}
+
+// 6,客户端请求行走
+type MoveReq struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	PlaneID string `protobuf:"bytes,1,opt,name=planeID,proto3" json:"planeID,omitempty"` //飞机id,从0开始
+}
+
+func (x *MoveReq) Reset() {
+	*x = MoveReq{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_Message_proto_msgTypes[36]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *MoveReq) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*MoveReq) ProtoMessage() {}
+
+func (x *MoveReq) ProtoReflect() protoreflect.Message {
+	mi := &file_Message_proto_msgTypes[36]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use MoveReq.ProtoReflect.Descriptor instead.
+func (*MoveReq) Descriptor() ([]byte, []int) {
+	return file_Message_proto_rawDescGZIP(), []int{36}
+}
+
+func (x *MoveReq) GetPlaneID() string {
+	if x != nil {
+		return x.PlaneID
+	}
+	return ""
+}
+
+// 7,通知移动结果
+type MoveRsp struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Result      *uint32         `protobuf:"varint,1,opt,name=result,proto3,oneof" json:"result,omitempty"`           //0表示成功,其他表示失败
+	SeatID      *uint32         `protobuf:"varint,2,opt,name=seatID,proto3,oneof" json:"seatID,omitempty"`           //起飞玩家座位id
+	PlaneID     string          `protobuf:"bytes,3,opt,name=planeID,proto3" json:"planeID,omitempty"`                //行走飞机ID
+	Step        *uint32         `protobuf:"varint,4,opt,name=step,proto3,oneof" json:"step,omitempty"`               //行走的步数
+	CurPosIndex *uint32         `protobuf:"varint,5,opt,name=curPosIndex,proto3,oneof" json:"curPosIndex,omitempty"` // 棋子当前相对于行走路线的索引
+	NextTurn    *uint32         `protobuf:"varint,6,opt,name=nextTurn,proto3,oneof" json:"nextTurn,omitempty"`       //下一个玩家
+	HasWin      *uint32         `protobuf:"varint,7,opt,name=hasWin,proto3,oneof" json:"hasWin,omitempty"`           //玩家是否已经获胜,1表示已经获胜,0表示还没有获胜
+	PlayerNum   uint32          `protobuf:"varint,8,opt,name=playerNum,proto3" json:"playerNum,omitempty"`           //玩家数
+	FinishEvent *FinishEventRsp `protobuf:"bytes,9,opt,name=finishEvent,proto3" json:"finishEvent,omitempty"`
+	TKickEvent  *TKickEventRsp  `protobuf:"bytes,10,opt,name=tKickEvent,proto3" json:"tKickEvent,omitempty"`
+	Players     []*PlayerRsp    `protobuf:"bytes,11,rep,name=players,proto3" json:"players,omitempty"`
+}
+
+func (x *MoveRsp) Reset() {
+	*x = MoveRsp{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_Message_proto_msgTypes[37]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *MoveRsp) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*MoveRsp) ProtoMessage() {}
+
+func (x *MoveRsp) ProtoReflect() protoreflect.Message {
+	mi := &file_Message_proto_msgTypes[37]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use MoveRsp.ProtoReflect.Descriptor instead.
+func (*MoveRsp) Descriptor() ([]byte, []int) {
+	return file_Message_proto_rawDescGZIP(), []int{37}
+}
+
+func (x *MoveRsp) GetResult() uint32 {
+	if x != nil && x.Result != nil {
+		return *x.Result
+	}
+	return 0
+}
+
+func (x *MoveRsp) GetSeatID() uint32 {
+	if x != nil && x.SeatID != nil {
+		return *x.SeatID
+	}
+	return 0
+}
+
+func (x *MoveRsp) GetPlaneID() string {
+	if x != nil {
+		return x.PlaneID
+	}
+	return ""
+}
+
+func (x *MoveRsp) GetStep() uint32 {
+	if x != nil && x.Step != nil {
+		return *x.Step
+	}
+	return 0
+}
+
+func (x *MoveRsp) GetCurPosIndex() uint32 {
+	if x != nil && x.CurPosIndex != nil {
+		return *x.CurPosIndex
+	}
+	return 0
+}
+
+func (x *MoveRsp) GetNextTurn() uint32 {
+	if x != nil && x.NextTurn != nil {
+		return *x.NextTurn
+	}
+	return 0
+}
+
+func (x *MoveRsp) GetHasWin() uint32 {
+	if x != nil && x.HasWin != nil {
+		return *x.HasWin
+	}
+	return 0
+}
+
+func (x *MoveRsp) GetPlayerNum() uint32 {
+	if x != nil {
+		return x.PlayerNum
+	}
+	return 0
+}
+
+func (x *MoveRsp) GetFinishEvent() *FinishEventRsp {
+	if x != nil {
+		return x.FinishEvent
+	}
+	return nil
+}
+
+func (x *MoveRsp) GetTKickEvent() *TKickEventRsp {
+	if x != nil {
+		return x.TKickEvent
+	}
+	return nil
+}
+
+func (x *MoveRsp) GetPlayers() []*PlayerRsp {
+	if x != nil {
+		return x.Players
+	}
+	return nil
+}
+
+// 9,客户端请求托管
+type TrusteeshipReq struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Trust bool `protobuf:"varint,1,opt,name=trust,proto3" json:"trust,omitempty"` //true表示托管,2表示不托管
+}
+
+func (x *TrusteeshipReq) Reset() {
+	*x = TrusteeshipReq{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_Message_proto_msgTypes[38]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *TrusteeshipReq) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*TrusteeshipReq) ProtoMessage() {}
+
+func (x *TrusteeshipReq) ProtoReflect() protoreflect.Message {
+	mi := &file_Message_proto_msgTypes[38]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use TrusteeshipReq.ProtoReflect.Descriptor instead.
+func (*TrusteeshipReq) Descriptor() ([]byte, []int) {
+	return file_Message_proto_rawDescGZIP(), []int{38}
+}
+
+func (x *TrusteeshipReq) GetTrust() bool {
+	if x != nil {
+		return x.Trust
+	}
+	return false
+}
+
+// 8,通知玩家托管
+type TrusteeshipRsp struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Trust  bool    `protobuf:"varint,1,opt,name=trust,proto3" json:"trust,omitempty"`         //true表示托管,false表示不托管
+	SeatID *uint32 `protobuf:"varint,2,opt,name=seatID,proto3,oneof" json:"seatID,omitempty"` //座位id
+}
+
+func (x *TrusteeshipRsp) Reset() {
+	*x = TrusteeshipRsp{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_Message_proto_msgTypes[39]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *TrusteeshipRsp) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*TrusteeshipRsp) ProtoMessage() {}
+
+func (x *TrusteeshipRsp) ProtoReflect() protoreflect.Message {
+	mi := &file_Message_proto_msgTypes[39]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use TrusteeshipRsp.ProtoReflect.Descriptor instead.
+func (*TrusteeshipRsp) Descriptor() ([]byte, []int) {
+	return file_Message_proto_rawDescGZIP(), []int{39}
+}
+
+func (x *TrusteeshipRsp) GetTrust() bool {
+	if x != nil {
+		return x.Trust
+	}
+	return false
+}
+
+func (x *TrusteeshipRsp) GetSeatID() uint32 {
+	if x != nil && x.SeatID != nil {
+		return *x.SeatID
+	}
+	return 0
+}
+
+// 退出游戏请求
+type QuitReq struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+}
+
+func (x *QuitReq) Reset() {
+	*x = QuitReq{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_Message_proto_msgTypes[40]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *QuitReq) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*QuitReq) ProtoMessage() {}
+
+func (x *QuitReq) ProtoReflect() protoreflect.Message {
+	mi := &file_Message_proto_msgTypes[40]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use QuitReq.ProtoReflect.Descriptor instead.
+func (*QuitReq) Descriptor() ([]byte, []int) {
+	return file_Message_proto_rawDescGZIP(), []int{40}
+}
+
+// 通知玩家退出游戏,直接剔除这个玩家
+type QuitRsp struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	PlayerStatus uint32  `protobuf:"varint,1,opt,name=playerStatus,proto3" json:"playerStatus,omitempty"` // 玩家的当前状态, 0、1 表示空位无玩家,2: sitdown, 3: ready, 4: play, 5: 胜利后观战, 6: 胜利后离开,7: 组队逃跑,8: 逃跑 10,观战玩家
+	SeatID       *uint32 `protobuf:"varint,2,opt,name=seatID,proto3,oneof" json:"seatID,omitempty"`       //座位号
+	NextTurn     *uint32 `protobuf:"varint,3,opt,name=nextTurn,proto3,oneof" json:"nextTurn,omitempty"`   //下一个座位号
+	Uid          string  `protobuf:"bytes,4,opt,name=uid,proto3" json:"uid,omitempty"`                    //用户id
+}
+
+func (x *QuitRsp) Reset() {
+	*x = QuitRsp{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_Message_proto_msgTypes[41]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *QuitRsp) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*QuitRsp) ProtoMessage() {}
+
+func (x *QuitRsp) ProtoReflect() protoreflect.Message {
+	mi := &file_Message_proto_msgTypes[41]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use QuitRsp.ProtoReflect.Descriptor instead.
+func (*QuitRsp) Descriptor() ([]byte, []int) {
+	return file_Message_proto_rawDescGZIP(), []int{41}
+}
+
+func (x *QuitRsp) GetPlayerStatus() uint32 {
+	if x != nil {
+		return x.PlayerStatus
+	}
+	return 0
+}
+
+func (x *QuitRsp) GetSeatID() uint32 {
+	if x != nil && x.SeatID != nil {
+		return *x.SeatID
+	}
+	return 0
+}
+
+func (x *QuitRsp) GetNextTurn() uint32 {
+	if x != nil && x.NextTurn != nil {
+		return *x.NextTurn
+	}
+	return 0
+}
+
+func (x *QuitRsp) GetUid() string {
+	if x != nil {
+		return x.Uid
+	}
+	return ""
+}
+
+// 通知玩家游戏结束
+type EndGameRsp struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	SeatID       []uint32 `protobuf:"varint,1,rep,packed,name=seatID,proto3" json:"seatID,omitempty"`     //座位号
+	PlayerStatus []string `protobuf:"bytes,2,rep,name=playerStatus,proto3" json:"playerStatus,omitempty"` //玩家状态
+	Kick         []uint32 `protobuf:"varint,3,rep,packed,name=kick,proto3" json:"kick,omitempty"`         //- 玩家当局撞棋数量
+	BeKick       []uint32 `protobuf:"varint,4,rep,packed,name=beKick,proto3" json:"beKick,omitempty"`     //- 玩家当局被撞棋数量
+	Money        []uint32 `protobuf:"varint,5,rep,packed,name=money,proto3" json:"money,omitempty"`       //- 胜方当局赢得金额
+}
+
+func (x *EndGameRsp) Reset() {
+	*x = EndGameRsp{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_Message_proto_msgTypes[42]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *EndGameRsp) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*EndGameRsp) ProtoMessage() {}
+
+func (x *EndGameRsp) ProtoReflect() protoreflect.Message {
+	mi := &file_Message_proto_msgTypes[42]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use EndGameRsp.ProtoReflect.Descriptor instead.
+func (*EndGameRsp) Descriptor() ([]byte, []int) {
+	return file_Message_proto_rawDescGZIP(), []int{42}
+}
+
+func (x *EndGameRsp) GetSeatID() []uint32 {
+	if x != nil {
+		return x.SeatID
+	}
+	return nil
+}
+
+func (x *EndGameRsp) GetPlayerStatus() []string {
+	if x != nil {
+		return x.PlayerStatus
+	}
+	return nil
+}
+
+func (x *EndGameRsp) GetKick() []uint32 {
+	if x != nil {
+		return x.Kick
+	}
+	return nil
+}
+
+func (x *EndGameRsp) GetBeKick() []uint32 {
+	if x != nil {
+		return x.BeKick
+	}
+	return nil
+}
+
+func (x *EndGameRsp) GetMoney() []uint32 {
+	if x != nil {
+		return x.Money
+	}
+	return nil
+}
+
+// 拉房失败解散游戏
+type DissolveTheGameReq struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+}
+
+func (x *DissolveTheGameReq) Reset() {
+	*x = DissolveTheGameReq{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_Message_proto_msgTypes[43]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *DissolveTheGameReq) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*DissolveTheGameReq) ProtoMessage() {}
+
+func (x *DissolveTheGameReq) ProtoReflect() protoreflect.Message {
+	mi := &file_Message_proto_msgTypes[43]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use DissolveTheGameReq.ProtoReflect.Descriptor instead.
+func (*DissolveTheGameReq) Descriptor() ([]byte, []int) {
+	return file_Message_proto_rawDescGZIP(), []int{43}
+}
+
+// 拉房失败解散游戏
+type DissolveTheGameRsp struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+}
+
+func (x *DissolveTheGameRsp) Reset() {
+	*x = DissolveTheGameRsp{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_Message_proto_msgTypes[44]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *DissolveTheGameRsp) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*DissolveTheGameRsp) ProtoMessage() {}
+
+func (x *DissolveTheGameRsp) ProtoReflect() protoreflect.Message {
+	mi := &file_Message_proto_msgTypes[44]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use DissolveTheGameRsp.ProtoReflect.Descriptor instead.
+func (*DissolveTheGameRsp) Descriptor() ([]byte, []int) {
+	return file_Message_proto_rawDescGZIP(), []int{44}
+}
+
+// pb解析失败
+type PbErrorRsp struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	MessageData string `protobuf:"bytes,1,opt,name=messageData,proto3" json:"messageData,omitempty"` //错误信息
+}
+
+func (x *PbErrorRsp) Reset() {
+	*x = PbErrorRsp{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_Message_proto_msgTypes[45]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *PbErrorRsp) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*PbErrorRsp) ProtoMessage() {}
+
+func (x *PbErrorRsp) ProtoReflect() protoreflect.Message {
+	mi := &file_Message_proto_msgTypes[45]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use PbErrorRsp.ProtoReflect.Descriptor instead.
+func (*PbErrorRsp) Descriptor() ([]byte, []int) {
+	return file_Message_proto_rawDescGZIP(), []int{45}
+}
+
+func (x *PbErrorRsp) GetMessageData() string {
+	if x != nil {
+		return x.MessageData
+	}
+	return ""
+}
+
+// //////////////////////////房间消息//////////////////////////////
+// 拉取房间列表 C->S, Cmd.MSGID_Get_Room_List
+type GetRoomListReq struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+}
+
+func (x *GetRoomListReq) Reset() {
+	*x = GetRoomListReq{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_Message_proto_msgTypes[46]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GetRoomListReq) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetRoomListReq) ProtoMessage() {}
+
+func (x *GetRoomListReq) ProtoReflect() protoreflect.Message {
+	mi := &file_Message_proto_msgTypes[46]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GetRoomListReq.ProtoReflect.Descriptor instead.
+func (*GetRoomListReq) Descriptor() ([]byte, []int) {
+	return file_Message_proto_rawDescGZIP(), []int{46}
+}
+
+// 拉取房间列表 S->C, Cmd.MSGID_Get_Room_List
+type GetRoomListRsp struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Result uint32 `protobuf:"varint,1,opt,name=result,proto3" json:"result,omitempty"` //结果
+}
+
+func (x *GetRoomListRsp) Reset() {
+	*x = GetRoomListRsp{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_Message_proto_msgTypes[47]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GetRoomListRsp) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetRoomListRsp) ProtoMessage() {}
+
+func (x *GetRoomListRsp) ProtoReflect() protoreflect.Message {
+	mi := &file_Message_proto_msgTypes[47]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GetRoomListRsp.ProtoReflect.Descriptor instead.
+func (*GetRoomListRsp) Descriptor() ([]byte, []int) {
+	return file_Message_proto_rawDescGZIP(), []int{47}
+}
+
+func (x *GetRoomListRsp) GetResult() uint32 {
+	if x != nil {
+		return x.Result
+	}
+	return 0
+}
+
+// 踢人通知 S->C, Cmd.MSGID_Kick_Notify
+type KickNotify struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Reason uint32 `protobuf:"varint,1,opt,name=reason,proto3" json:"reason,omitempty"`
+}
+
+func (x *KickNotify) Reset() {
+	*x = KickNotify{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_Message_proto_msgTypes[48]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *KickNotify) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*KickNotify) ProtoMessage() {}
+
+func (x *KickNotify) ProtoReflect() protoreflect.Message {
+	mi := &file_Message_proto_msgTypes[48]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use KickNotify.ProtoReflect.Descriptor instead.
+func (*KickNotify) Descriptor() ([]byte, []int) {
+	return file_Message_proto_rawDescGZIP(), []int{48}
+}
+
+func (x *KickNotify) GetReason() uint32 {
+	if x != nil {
+		return x.Reason
+	}
+	return 0
+}
+
+// 退出客户端房主变更
+type RoomChangeOfHomeownerRsp struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Uid string `protobuf:"bytes,1,opt,name=uid,proto3" json:"uid,omitempty"` //玩家ID
+}
+
+func (x *RoomChangeOfHomeownerRsp) Reset() {
+	*x = RoomChangeOfHomeownerRsp{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_Message_proto_msgTypes[49]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *RoomChangeOfHomeownerRsp) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*RoomChangeOfHomeownerRsp) ProtoMessage() {}
+
+func (x *RoomChangeOfHomeownerRsp) ProtoReflect() protoreflect.Message {
+	mi := &file_Message_proto_msgTypes[49]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use RoomChangeOfHomeownerRsp.ProtoReflect.Descriptor instead.
+func (*RoomChangeOfHomeownerRsp) Descriptor() ([]byte, []int) {
+	return file_Message_proto_rawDescGZIP(), []int{49}
+}
+
+func (x *RoomChangeOfHomeownerRsp) GetUid() string {
+	if x != nil {
+		return x.Uid
+	}
+	return ""
+}
+
+type GetUserMoneyReq struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Uid string `protobuf:"bytes,1,opt,name=uid,proto3" json:"uid,omitempty"` //玩家ID
+}
+
+func (x *GetUserMoneyReq) Reset() {
+	*x = GetUserMoneyReq{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_Message_proto_msgTypes[50]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GetUserMoneyReq) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetUserMoneyReq) ProtoMessage() {}
+
+func (x *GetUserMoneyReq) ProtoReflect() protoreflect.Message {
+	mi := &file_Message_proto_msgTypes[50]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GetUserMoneyReq.ProtoReflect.Descriptor instead.
+func (*GetUserMoneyReq) Descriptor() ([]byte, []int) {
+	return file_Message_proto_rawDescGZIP(), []int{50}
+}
+
+func (x *GetUserMoneyReq) GetUid() string {
+	if x != nil {
+		return x.Uid
+	}
+	return ""
+}
+
+type GetUserMoneyRsp struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Money *uint32 `protobuf:"varint,1,opt,name=money,proto3,oneof" json:"money,omitempty"` //玩家金币
+}
+
+func (x *GetUserMoneyRsp) Reset() {
+	*x = GetUserMoneyRsp{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_Message_proto_msgTypes[51]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GetUserMoneyRsp) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetUserMoneyRsp) ProtoMessage() {}
+
+func (x *GetUserMoneyRsp) ProtoReflect() protoreflect.Message {
+	mi := &file_Message_proto_msgTypes[51]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GetUserMoneyRsp.ProtoReflect.Descriptor instead.
+func (*GetUserMoneyRsp) Descriptor() ([]byte, []int) {
+	return file_Message_proto_rawDescGZIP(), []int{51}
+}
+
+func (x *GetUserMoneyRsp) GetMoney() uint32 {
+	if x != nil && x.Money != nil {
+		return *x.Money
+	}
+	return 0
+}
+
+type DiscReq struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Uid    string `protobuf:"bytes,1,opt,name=uid,proto3" json:"uid,omitempty"`        //玩家ID
+	RoomId uint32 `protobuf:"varint,2,opt,name=roomId,proto3" json:"roomId,omitempty"` //房间ID
+}
+
+func (x *DiscReq) Reset() {
+	*x = DiscReq{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_Message_proto_msgTypes[52]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *DiscReq) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*DiscReq) ProtoMessage() {}
+
+func (x *DiscReq) ProtoReflect() protoreflect.Message {
+	mi := &file_Message_proto_msgTypes[52]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use DiscReq.ProtoReflect.Descriptor instead.
+func (*DiscReq) Descriptor() ([]byte, []int) {
+	return file_Message_proto_rawDescGZIP(), []int{52}
+}
+
+func (x *DiscReq) GetUid() string {
+	if x != nil {
+		return x.Uid
+	}
+	return ""
+}
+
+func (x *DiscReq) GetRoomId() uint32 {
+	if x != nil {
+		return x.RoomId
+	}
+	return 0
+}
+
+type RoomQuitReq struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+}
+
+func (x *RoomQuitReq) Reset() {
+	*x = RoomQuitReq{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_Message_proto_msgTypes[53]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *RoomQuitReq) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*RoomQuitReq) ProtoMessage() {}
+
+func (x *RoomQuitReq) ProtoReflect() protoreflect.Message {
+	mi := &file_Message_proto_msgTypes[53]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use RoomQuitReq.ProtoReflect.Descriptor instead.
+func (*RoomQuitReq) Descriptor() ([]byte, []int) {
+	return file_Message_proto_rawDescGZIP(), []int{53}
+}
+
+type RoomRestartReq struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+}
+
+func (x *RoomRestartReq) Reset() {
+	*x = RoomRestartReq{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_Message_proto_msgTypes[54]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *RoomRestartReq) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*RoomRestartReq) ProtoMessage() {}
+
+func (x *RoomRestartReq) ProtoReflect() protoreflect.Message {
+	mi := &file_Message_proto_msgTypes[54]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use RoomRestartReq.ProtoReflect.Descriptor instead.
+func (*RoomRestartReq) Descriptor() ([]byte, []int) {
+	return file_Message_proto_rawDescGZIP(), []int{54}
+}
+
+type SendMsgReq struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Data string `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"` //消息数据
+}
+
+func (x *SendMsgReq) Reset() {
+	*x = SendMsgReq{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_Message_proto_msgTypes[55]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *SendMsgReq) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SendMsgReq) ProtoMessage() {}
+
+func (x *SendMsgReq) ProtoReflect() protoreflect.Message {
+	mi := &file_Message_proto_msgTypes[55]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use SendMsgReq.ProtoReflect.Descriptor instead.
+func (*SendMsgReq) Descriptor() ([]byte, []int) {
+	return file_Message_proto_rawDescGZIP(), []int{55}
+}
+
+func (x *SendMsgReq) GetData() string {
+	if x != nil {
+		return x.Data
+	}
+	return ""
+}
+
+type SendMsgRsp struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Data string `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"` //消息数据
+	Uid  string `protobuf:"bytes,2,opt,name=uid,proto3" json:"uid,omitempty"`   //消息数据
+}
+
+func (x *SendMsgRsp) Reset() {
+	*x = SendMsgRsp{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_Message_proto_msgTypes[56]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *SendMsgRsp) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SendMsgRsp) ProtoMessage() {}
+
+func (x *SendMsgRsp) ProtoReflect() protoreflect.Message {
+	mi := &file_Message_proto_msgTypes[56]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use SendMsgRsp.ProtoReflect.Descriptor instead.
+func (*SendMsgRsp) Descriptor() ([]byte, []int) {
+	return file_Message_proto_rawDescGZIP(), []int{56}
+}
+
+func (x *SendMsgRsp) GetData() string {
+	if x != nil {
+		return x.Data
+	}
+	return ""
+}
+
+func (x *SendMsgRsp) GetUid() string {
+	if x != nil {
+		return x.Uid
+	}
+	return ""
+}
+
+var File_Message_proto protoreflect.FileDescriptor
+
+var file_Message_proto_rawDesc = []byte{
+	0x0a, 0x0d, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12,
+	0x09, 0x42, 0x42, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x0f, 0x0a, 0x0d, 0x48, 0x65,
+	0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x50, 0x75, 0x73, 0x68, 0x22, 0x34, 0x0a, 0x08, 0x4c,
+	0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x01,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x61, 0x73,
+	0x73, 0x57, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x61, 0x73, 0x73, 0x57,
+	0x64, 0x22, 0x54, 0x0a, 0x08, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x73, 0x70, 0x12, 0x16, 0x0a,
+	0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x72,
+	0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x49,
+	0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x49,
+	0x64, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x73, 0x4e, 0x65, 0x77, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08,
+	0x52, 0x05, 0x69, 0x73, 0x4e, 0x65, 0x77, 0x22, 0x96, 0x02, 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61,
+	0x74, 0x65, 0x47, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x6f, 0x64,
+	0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x12, 0x1c, 0x0a,
+	0x09, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x4e, 0x75, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d,
+	0x52, 0x09, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x4e, 0x75, 0x6d, 0x12, 0x22, 0x0a, 0x0c, 0x61,
+	0x64, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x46, 0x65, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28,
+	0x0d, 0x52, 0x0c, 0x61, 0x64, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x46, 0x65, 0x65, 0x12,
+	0x16, 0x0a, 0x06, 0x69, 0x73, 0x52, 0x6f, 0x6f, 0x6d, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52,
+	0x06, 0x69, 0x73, 0x52, 0x6f, 0x6f, 0x6d, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x05,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d,
+	0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a,
+	0x07, 0x68, 0x65, 0x61, 0x64, 0x49, 0x6d, 0x67, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07,
+	0x68, 0x65, 0x61, 0x64, 0x49, 0x6d, 0x67, 0x12, 0x19, 0x0a, 0x05, 0x6d, 0x6f, 0x6e, 0x65, 0x79,
+	0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x00, 0x52, 0x05, 0x6d, 0x6f, 0x6e, 0x65, 0x79, 0x88,
+	0x01, 0x01, 0x12, 0x23, 0x0a, 0x0a, 0x63, 0x68, 0x61, 0x74, 0x52, 0x6f, 0x6f, 0x6d, 0x49, 0x64,
+	0x18, 0x09, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x01, 0x52, 0x0a, 0x63, 0x68, 0x61, 0x74, 0x52, 0x6f,
+	0x6f, 0x6d, 0x49, 0x64, 0x88, 0x01, 0x01, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x6d, 0x6f, 0x6e, 0x65,
+	0x79, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x63, 0x68, 0x61, 0x74, 0x52, 0x6f, 0x6f, 0x6d, 0x49, 0x64,
+	0x22, 0x9c, 0x01, 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x47, 0x61, 0x6d, 0x65, 0x52,
+	0x73, 0x70, 0x12, 0x1b, 0x0a, 0x06, 0x72, 0x6f, 0x6f, 0x6d, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x0d, 0x48, 0x00, 0x52, 0x06, 0x72, 0x6f, 0x6f, 0x6d, 0x49, 0x64, 0x88, 0x01, 0x01, 0x12,
+	0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x69,
+	0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x68, 0x65, 0x61, 0x64, 0x49, 0x6d, 0x67,
+	0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x68, 0x65, 0x61, 0x64, 0x49, 0x6d, 0x67, 0x12,
+	0x19, 0x0a, 0x05, 0x6d, 0x6f, 0x6e, 0x65, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x01,
+	0x52, 0x05, 0x6d, 0x6f, 0x6e, 0x65, 0x79, 0x88, 0x01, 0x01, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x72,
+	0x6f, 0x6f, 0x6d, 0x49, 0x64, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x6d, 0x6f, 0x6e, 0x65, 0x79, 0x22,
+	0x83, 0x02, 0x0a, 0x0b, 0x52, 0x6f, 0x6f, 0x6d, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x73, 0x70, 0x12,
+	0x1b, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x48,
+	0x00, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x88, 0x01, 0x01, 0x12, 0x14, 0x0a, 0x05,
+	0x6d, 0x6f, 0x6e, 0x65, 0x79, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0d, 0x52, 0x05, 0x6d, 0x6f, 0x6e,
+	0x65, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x49, 0x44, 0x18, 0x03,
+	0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x49, 0x44, 0x12, 0x12,
+	0x0a, 0x04, 0x6e, 0x69, 0x63, 0x6b, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x69,
+	0x63, 0x6b, 0x12, 0x18, 0x0a, 0x07, 0x68, 0x65, 0x61, 0x64, 0x55, 0x72, 0x6c, 0x18, 0x05, 0x20,
+	0x03, 0x28, 0x09, 0x52, 0x07, 0x68, 0x65, 0x61, 0x64, 0x55, 0x72, 0x6c, 0x12, 0x16, 0x0a, 0x06,
+	0x73, 0x65, 0x61, 0x74, 0x49, 0x64, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0d, 0x52, 0x06, 0x73, 0x65,
+	0x61, 0x74, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x06, 0x20, 0x01,
+	0x28, 0x0d, 0x52, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x6c, 0x61, 0x79,
+	0x65, 0x72, 0x4e, 0x75, 0x6d, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x70, 0x6c, 0x61,
+	0x79, 0x65, 0x72, 0x4e, 0x75, 0x6d, 0x12, 0x22, 0x0a, 0x0c, 0x61, 0x64, 0x6d, 0x69, 0x73, 0x73,
+	0x69, 0x6f, 0x6e, 0x46, 0x65, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x61, 0x64,
+	0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x46, 0x65, 0x65, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x72,
+	0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0xba, 0x01, 0x0a, 0x0b, 0x4a, 0x6f, 0x69, 0x6e, 0x52, 0x6f,
+	0x6f, 0x6d, 0x52, 0x65, 0x71, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18,
+	0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x68,
+	0x65, 0x61, 0x64, 0x49, 0x6d, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x68, 0x65,
+	0x61, 0x64, 0x49, 0x6d, 0x67, 0x12, 0x19, 0x0a, 0x05, 0x6d, 0x6f, 0x6e, 0x65, 0x79, 0x18, 0x04,
+	0x20, 0x01, 0x28, 0x0d, 0x48, 0x00, 0x52, 0x05, 0x6d, 0x6f, 0x6e, 0x65, 0x79, 0x88, 0x01, 0x01,
+	0x12, 0x1b, 0x0a, 0x06, 0x72, 0x6f, 0x6f, 0x6d, 0x49, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d,
+	0x48, 0x01, 0x52, 0x06, 0x72, 0x6f, 0x6f, 0x6d, 0x49, 0x64, 0x88, 0x01, 0x01, 0x12, 0x1e, 0x0a,
+	0x0a, 0x72, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x42, 0x74, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28,
+	0x08, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x42, 0x74, 0x6e, 0x42, 0x08, 0x0a,
+	0x06, 0x5f, 0x6d, 0x6f, 0x6e, 0x65, 0x79, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x72, 0x6f, 0x6f, 0x6d,
+	0x49, 0x64, 0x22, 0x23, 0x0a, 0x0f, 0x52, 0x6f, 0x6f, 0x6d, 0x4b, 0x69, 0x63, 0x6b, 0x55, 0x73,
+	0x65, 0x72, 0x52, 0x65, 0x71, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x03, 0x75, 0x69, 0x64, 0x22, 0x37, 0x0a, 0x0f, 0x52, 0x6f, 0x6f, 0x6d, 0x4b,
+	0x69, 0x63, 0x6b, 0x55, 0x73, 0x65, 0x72, 0x52, 0x73, 0x70, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69,
+	0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04,
+	0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65,
+	0x22, 0x23, 0x0a, 0x0f, 0x52, 0x6f, 0x6f, 0x6d, 0x51, 0x75, 0x69, 0x74, 0x55, 0x73, 0x65, 0x72,
+	0x52, 0x65, 0x71, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x03, 0x75, 0x69, 0x64, 0x22, 0x7d, 0x0a, 0x0d, 0x52, 0x6f, 0x6f, 0x6d, 0x49, 0x6e, 0x76,
+	0x69, 0x74, 0x65, 0x52, 0x65, 0x71, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x23, 0x0a, 0x0a, 0x63, 0x68, 0x61, 0x74,
+	0x52, 0x6f, 0x6f, 0x6d, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x00, 0x52, 0x0a,
+	0x63, 0x68, 0x61, 0x74, 0x52, 0x6f, 0x6f, 0x6d, 0x49, 0x64, 0x88, 0x01, 0x01, 0x12, 0x1b, 0x0a,
+	0x06, 0x72, 0x6f, 0x6f, 0x6d, 0x49, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x01, 0x52,
+	0x06, 0x72, 0x6f, 0x6f, 0x6d, 0x49, 0x64, 0x88, 0x01, 0x01, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x63,
+	0x68, 0x61, 0x74, 0x52, 0x6f, 0x6f, 0x6d, 0x49, 0x64, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x72, 0x6f,
+	0x6f, 0x6d, 0x49, 0x64, 0x22, 0x37, 0x0a, 0x0d, 0x52, 0x6f, 0x6f, 0x6d, 0x49, 0x6e, 0x76, 0x69,
+	0x74, 0x65, 0x52, 0x73, 0x70, 0x12, 0x1b, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18,
+	0x01, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x00, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x88,
+	0x01, 0x01, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x37, 0x0a,
+	0x0f, 0x52, 0x6f, 0x6f, 0x6d, 0x51, 0x75, 0x69, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x73, 0x70,
+	0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75,
+	0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0xe8, 0x02, 0x0a, 0x0f, 0x4a, 0x6f, 0x69, 0x6e, 0x52,
+	0x6f, 0x6f, 0x6d, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x73, 0x70, 0x12, 0x1b, 0x0a, 0x06, 0x72, 0x65,
+	0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x00, 0x52, 0x06, 0x72, 0x65,
+	0x73, 0x75, 0x6c, 0x74, 0x88, 0x01, 0x01, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x6f, 0x6e, 0x65, 0x79,
+	0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d, 0x6f, 0x6e, 0x65, 0x79, 0x12, 0x1a, 0x0a,
+	0x08, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x49, 0x44, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x08, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x49, 0x44, 0x12, 0x22, 0x0a, 0x0c, 0x70, 0x6c, 0x61,
+	0x79, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52,
+	0x0c, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x18, 0x0a,
+	0x07, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x49, 0x44, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07,
+	0x74, 0x61, 0x62, 0x6c, 0x65, 0x49, 0x44, 0x12, 0x1b, 0x0a, 0x06, 0x73, 0x65, 0x61, 0x74, 0x49,
+	0x44, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x01, 0x52, 0x06, 0x73, 0x65, 0x61, 0x74, 0x49,
+	0x44, 0x88, 0x01, 0x01, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x69, 0x63, 0x6b, 0x18, 0x07, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x04, 0x6e, 0x69, 0x63, 0x6b, 0x12, 0x18, 0x0a, 0x07, 0x68, 0x65, 0x61, 0x64,
+	0x55, 0x72, 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x68, 0x65, 0x61, 0x64, 0x55,
+	0x72, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x67, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x18, 0x09, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x06, 0x67, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x12, 0x21, 0x0a, 0x09, 0x70, 0x6c,
+	0x61, 0x79, 0x65, 0x72, 0x4e, 0x75, 0x6d, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x02, 0x52,
+	0x09, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x4e, 0x75, 0x6d, 0x88, 0x01, 0x01, 0x12, 0x1e, 0x0a,
+	0x0a, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28,
+	0x0d, 0x52, 0x0a, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x42, 0x09, 0x0a,
+	0x07, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x73, 0x65, 0x61,
+	0x74, 0x49, 0x44, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x4e, 0x75,
+	0x6d, 0x22, 0x47, 0x0a, 0x0b, 0x52, 0x6f, 0x6f, 0x6d, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71,
+	0x12, 0x1b, 0x0a, 0x06, 0x72, 0x6f, 0x6f, 0x6d, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d,
+	0x48, 0x00, 0x52, 0x06, 0x72, 0x6f, 0x6f, 0x6d, 0x49, 0x64, 0x88, 0x01, 0x01, 0x12, 0x10, 0x0a,
+	0x03, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x69, 0x64, 0x42,
+	0x09, 0x0a, 0x07, 0x5f, 0x72, 0x6f, 0x6f, 0x6d, 0x49, 0x64, 0x22, 0x10, 0x0a, 0x0e, 0x43, 0x61,
+	0x6e, 0x63, 0x65, 0x6c, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x71, 0x22, 0x4a, 0x0a, 0x0e,
+	0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x73, 0x70, 0x12, 0x1b,
+	0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x00,
+	0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x88, 0x01, 0x01, 0x12, 0x10, 0x0a, 0x03, 0x75,
+	0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x69, 0x64, 0x42, 0x09, 0x0a,
+	0x07, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x32, 0x0a, 0x08, 0x4d, 0x61, 0x74, 0x63,
+	0x68, 0x52, 0x73, 0x70, 0x12, 0x1b, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01,
+	0x20, 0x01, 0x28, 0x0d, 0x48, 0x00, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x88, 0x01,
+	0x01, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0xba, 0x01, 0x0a,
+	0x10, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x69, 0x6e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x73,
+	0x70, 0x12, 0x1b, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28,
+	0x0d, 0x48, 0x00, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x88, 0x01, 0x01, 0x12, 0x1a,
+	0x0a, 0x08, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x08, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x49, 0x44, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x69,
+	0x63, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x69, 0x63, 0x6b, 0x12, 0x18,
+	0x0a, 0x07, 0x68, 0x65, 0x61, 0x64, 0x55, 0x72, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x07, 0x68, 0x65, 0x61, 0x64, 0x55, 0x72, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x67, 0x65, 0x6e, 0x64,
+	0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x67, 0x65, 0x6e, 0x64, 0x65, 0x72,
+	0x12, 0x1c, 0x0a, 0x09, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x4e, 0x75, 0x6d, 0x18, 0x06, 0x20,
+	0x01, 0x28, 0x0d, 0x52, 0x09, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x4e, 0x75, 0x6d, 0x42, 0x09,
+	0x0a, 0x07, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x12, 0x0a, 0x10, 0x52, 0x6f, 0x6f,
+	0x6d, 0x53, 0x74, 0x61, 0x72, 0x74, 0x47, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x22, 0x12, 0x0a,
+	0x10, 0x52, 0x6f, 0x6f, 0x6d, 0x53, 0x74, 0x61, 0x72, 0x74, 0x47, 0x61, 0x6d, 0x65, 0x52, 0x73,
+	0x70, 0x22, 0x3a, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f,
+	0x52, 0x65, 0x71, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x6f, 0x6f, 0x6d, 0x49, 0x64, 0x18,
+	0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x72, 0x6f, 0x6f, 0x6d, 0x49, 0x64, 0x22, 0x1f, 0x0a,
+	0x0b, 0x4b, 0x69, 0x63, 0x6b, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x12, 0x10, 0x0a, 0x03,
+	0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x69, 0x64, 0x22, 0x88,
+	0x04, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x73,
+	0x70, 0x12, 0x1b, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28,
+	0x0d, 0x48, 0x00, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x88, 0x01, 0x01, 0x12, 0x14,
+	0x0a, 0x05, 0x6d, 0x6f, 0x6e, 0x65, 0x79, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x6d,
+	0x6f, 0x6e, 0x65, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x49, 0x44,
+	0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x49, 0x44,
+	0x12, 0x22, 0x0a, 0x0c, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73,
+	0x18, 0x04, 0x20, 0x03, 0x28, 0x0d, 0x52, 0x0c, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x53, 0x74,
+	0x61, 0x74, 0x75, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x49, 0x44, 0x18,
+	0x05, 0x20, 0x03, 0x28, 0x0d, 0x52, 0x07, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x49, 0x44, 0x12, 0x16,
+	0x0a, 0x06, 0x73, 0x65, 0x61, 0x74, 0x49, 0x44, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0d, 0x52, 0x06,
+	0x73, 0x65, 0x61, 0x74, 0x49, 0x44, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x69, 0x63, 0x6b, 0x18, 0x07,
+	0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x69, 0x63, 0x6b, 0x12, 0x18, 0x0a, 0x07, 0x68, 0x65,
+	0x61, 0x64, 0x55, 0x72, 0x6c, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x68, 0x65, 0x61,
+	0x64, 0x55, 0x72, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x67, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x18, 0x09,
+	0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x67, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x12, 0x1c, 0x0a, 0x09,
+	0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x4e, 0x75, 0x6d, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0d, 0x52,
+	0x09, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x4e, 0x75, 0x6d, 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x6c,
+	0x61, 0x79, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0d, 0x52, 0x0a,
+	0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x12, 0x23, 0x0a, 0x0a, 0x73, 0x65,
+	0x6c, 0x66, 0x53, 0x65, 0x61, 0x74, 0x49, 0x64, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x01,
+	0x52, 0x0a, 0x73, 0x65, 0x6c, 0x66, 0x53, 0x65, 0x61, 0x74, 0x49, 0x64, 0x88, 0x01, 0x01, 0x12,
+	0x2d, 0x0a, 0x0f, 0x77, 0x61, 0x74, 0x63, 0x68, 0x69, 0x6e, 0x67, 0x50, 0x6c, 0x61, 0x79, 0x65,
+	0x72, 0x73, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x02, 0x52, 0x0f, 0x77, 0x61, 0x74, 0x63,
+	0x68, 0x69, 0x6e, 0x67, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x88, 0x01, 0x01, 0x12, 0x21,
+	0x0a, 0x09, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x18, 0x0e, 0x20, 0x01, 0x28,
+	0x0d, 0x48, 0x03, 0x52, 0x09, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x88, 0x01,
+	0x01, 0x12, 0x1a, 0x0a, 0x08, 0x67, 0x61, 0x6d, 0x65, 0x54, 0x79, 0x70, 0x65, 0x18, 0x0f, 0x20,
+	0x01, 0x28, 0x0d, 0x52, 0x08, 0x67, 0x61, 0x6d, 0x65, 0x54, 0x79, 0x70, 0x65, 0x42, 0x09, 0x0a,
+	0x07, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x73, 0x65, 0x6c,
+	0x66, 0x53, 0x65, 0x61, 0x74, 0x49, 0x64, 0x42, 0x12, 0x0a, 0x10, 0x5f, 0x77, 0x61, 0x74, 0x63,
+	0x68, 0x69, 0x6e, 0x67, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x42, 0x0c, 0x0a, 0x0a, 0x5f,
+	0x63, 0x6f, 0x75, 0x6e, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x22, 0x7a, 0x0a, 0x0d, 0x54, 0x4b, 0x69,
+	0x63, 0x6b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x73, 0x70, 0x12, 0x21, 0x0a, 0x09, 0x50, 0x6c,
+	0x61, 0x79, 0x65, 0x72, 0x4e, 0x75, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x00, 0x52,
+	0x09, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x4e, 0x75, 0x6d, 0x88, 0x01, 0x01, 0x12, 0x38, 0x0a,
+	0x0a, 0x6b, 0x69, 0x63, 0x6b, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x18, 0x02, 0x20, 0x03, 0x28,
+	0x0b, 0x32, 0x18, 0x2e, 0x42, 0x42, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x4b, 0x69,
+	0x63, 0x6b, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x73, 0x70, 0x52, 0x0a, 0x6b, 0x69, 0x63,
+	0x6b, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x50, 0x6c, 0x61, 0x79,
+	0x65, 0x72, 0x4e, 0x75, 0x6d, 0x22, 0x7f, 0x0a, 0x0d, 0x4b, 0x69, 0x63, 0x6b, 0x50, 0x6c, 0x61,
+	0x79, 0x65, 0x72, 0x52, 0x73, 0x70, 0x12, 0x1b, 0x0a, 0x06, 0x73, 0x65, 0x61, 0x74, 0x49, 0x64,
+	0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x00, 0x52, 0x06, 0x73, 0x65, 0x61, 0x74, 0x49, 0x64,
+	0x88, 0x01, 0x01, 0x12, 0x1f, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x4e, 0x75, 0x6d, 0x18,
+	0x02, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x01, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x4e, 0x75,
+	0x6d, 0x88, 0x01, 0x01, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x49, 0x44, 0x18,
+	0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x49, 0x44, 0x42, 0x09,
+	0x0a, 0x07, 0x5f, 0x73, 0x65, 0x61, 0x74, 0x49, 0x64, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x70, 0x6c,
+	0x61, 0x6e, 0x65, 0x4e, 0x75, 0x6d, 0x22, 0x52, 0x0a, 0x0e, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68,
+	0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x73, 0x70, 0x12, 0x1b, 0x0a, 0x06, 0x73, 0x65, 0x61, 0x74,
+	0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x00, 0x52, 0x06, 0x73, 0x65, 0x61, 0x74,
+	0x49, 0x64, 0x88, 0x01, 0x01, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x49, 0x64,
+	0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x49, 0x64, 0x42,
+	0x09, 0x0a, 0x07, 0x5f, 0x73, 0x65, 0x61, 0x74, 0x49, 0x64, 0x22, 0x60, 0x0a, 0x09, 0x50, 0x6c,
+	0x61, 0x79, 0x65, 0x72, 0x52, 0x73, 0x70, 0x12, 0x1b, 0x0a, 0x06, 0x73, 0x65, 0x61, 0x74, 0x49,
+	0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x00, 0x52, 0x06, 0x73, 0x65, 0x61, 0x74, 0x49,
+	0x64, 0x88, 0x01, 0x01, 0x12, 0x2b, 0x0a, 0x06, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x73, 0x18, 0x02,
+	0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x42, 0x42, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
+	0x2e, 0x50, 0x6c, 0x61, 0x6e, 0x65, 0x52, 0x73, 0x70, 0x52, 0x06, 0x70, 0x6c, 0x61, 0x6e, 0x65,
+	0x73, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x73, 0x65, 0x61, 0x74, 0x49, 0x64, 0x22, 0x95, 0x01, 0x0a,
+	0x08, 0x50, 0x6c, 0x61, 0x6e, 0x65, 0x52, 0x73, 0x70, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x6c, 0x61,
+	0x6e, 0x65, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x6c, 0x61, 0x6e,
+	0x65, 0x49, 0x64, 0x12, 0x27, 0x0a, 0x0c, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x49, 0x6e,
+	0x64, 0x65, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x00, 0x52, 0x0c, 0x63, 0x75, 0x72,
+	0x72, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x88, 0x01, 0x01, 0x12, 0x25, 0x0a, 0x0b,
+	0x70, 0x6c, 0x61, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28,
+	0x0d, 0x48, 0x01, 0x52, 0x0b, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73,
+	0x88, 0x01, 0x01, 0x42, 0x0f, 0x0a, 0x0d, 0x5f, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x49,
+	0x6e, 0x64, 0x65, 0x78, 0x42, 0x0e, 0x0a, 0x0c, 0x5f, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x53, 0x74,
+	0x61, 0x74, 0x75, 0x73, 0x22, 0x2e, 0x0a, 0x0a, 0x52, 0x6f, 0x6f, 0x6d, 0x44, 0x6a, 0x73, 0x52,
+	0x73, 0x70, 0x12, 0x17, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d,
+	0x48, 0x00, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x88, 0x01, 0x01, 0x42, 0x07, 0x0a, 0x05, 0x5f,
+	0x74, 0x69, 0x6d, 0x65, 0x22, 0xc5, 0x02, 0x0a, 0x0f, 0x52, 0x6f, 0x6f, 0x6d, 0x4a, 0x6f, 0x69,
+	0x6e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x73, 0x70, 0x12, 0x1b, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75,
+	0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x00, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75,
+	0x6c, 0x74, 0x88, 0x01, 0x01, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x6f, 0x6e, 0x65, 0x79, 0x18, 0x02,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d, 0x6f, 0x6e, 0x65, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x70,
+	0x6c, 0x61, 0x79, 0x65, 0x72, 0x49, 0x44, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70,
+	0x6c, 0x61, 0x79, 0x65, 0x72, 0x49, 0x44, 0x12, 0x22, 0x0a, 0x0c, 0x70, 0x6c, 0x61, 0x79, 0x65,
+	0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x70,
+	0x6c, 0x61, 0x79, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x74,
+	0x61, 0x62, 0x6c, 0x65, 0x49, 0x44, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x74, 0x61,
+	0x62, 0x6c, 0x65, 0x49, 0x44, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x65, 0x61, 0x74, 0x49, 0x44, 0x18,
+	0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x73, 0x65, 0x61, 0x74, 0x49, 0x44, 0x12, 0x12, 0x0a,
+	0x04, 0x6e, 0x69, 0x63, 0x6b, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x69, 0x63,
+	0x6b, 0x12, 0x18, 0x0a, 0x07, 0x68, 0x65, 0x61, 0x64, 0x55, 0x72, 0x6c, 0x18, 0x08, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x07, 0x68, 0x65, 0x61, 0x64, 0x55, 0x72, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x67,
+	0x65, 0x6e, 0x64, 0x65, 0x72, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x67, 0x65, 0x6e,
+	0x64, 0x65, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x4e, 0x75, 0x6d,
+	0x18, 0x0a, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x4e, 0x75,
+	0x6d, 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x18,
+	0x0b, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x54, 0x79, 0x70,
+	0x65, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x92, 0x01, 0x0a,
+	0x0c, 0x47, 0x61, 0x6d, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x73, 0x70, 0x12, 0x1b, 0x0a,
+	0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x00, 0x52,
+	0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x88, 0x01, 0x01, 0x12, 0x1b, 0x0a, 0x06, 0x73, 0x65,
+	0x61, 0x74, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x01, 0x52, 0x06, 0x73, 0x65,
+	0x61, 0x74, 0x49, 0x44, 0x88, 0x01, 0x01, 0x12, 0x23, 0x0a, 0x0a, 0x63, 0x61, 0x73, 0x74, 0x53,
+	0x65, 0x63, 0x6f, 0x6e, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x02, 0x52, 0x0a, 0x63,
+	0x61, 0x73, 0x74, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x88, 0x01, 0x01, 0x42, 0x09, 0x0a, 0x07,
+	0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x73, 0x65, 0x61, 0x74,
+	0x49, 0x44, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x63, 0x61, 0x73, 0x74, 0x53, 0x65, 0x63, 0x6f, 0x6e,
+	0x64, 0x22, 0x11, 0x0a, 0x0f, 0x54, 0x68, 0x72, 0x6f, 0x77, 0x54, 0x68, 0x65, 0x44, 0x69, 0x63,
+	0x65, 0x52, 0x65, 0x71, 0x22, 0xb7, 0x02, 0x0a, 0x0f, 0x54, 0x68, 0x72, 0x6f, 0x77, 0x54, 0x68,
+	0x65, 0x44, 0x69, 0x63, 0x65, 0x52, 0x73, 0x70, 0x12, 0x1b, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75,
+	0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x00, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75,
+	0x6c, 0x74, 0x88, 0x01, 0x01, 0x12, 0x1b, 0x0a, 0x06, 0x73, 0x65, 0x61, 0x74, 0x49, 0x44, 0x18,
+	0x02, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x01, 0x52, 0x06, 0x73, 0x65, 0x61, 0x74, 0x49, 0x44, 0x88,
+	0x01, 0x01, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28,
+	0x0d, 0x52, 0x05, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x23, 0x0a, 0x0a, 0x73, 0x6b, 0x69, 0x70,
+	0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x02, 0x52, 0x0a,
+	0x73, 0x6b, 0x69, 0x70, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x88, 0x01, 0x01, 0x12, 0x1f, 0x0a,
+	0x08, 0x6e, 0x65, 0x78, 0x74, 0x54, 0x75, 0x72, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x48,
+	0x03, 0x52, 0x08, 0x6e, 0x65, 0x78, 0x74, 0x54, 0x75, 0x72, 0x6e, 0x88, 0x01, 0x01, 0x12, 0x1f,
+	0x0a, 0x08, 0x61, 0x75, 0x74, 0x6f, 0x4d, 0x6f, 0x76, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d,
+	0x48, 0x04, 0x52, 0x08, 0x61, 0x75, 0x74, 0x6f, 0x4d, 0x6f, 0x76, 0x65, 0x88, 0x01, 0x01, 0x12,
+	0x2e, 0x0a, 0x07, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b,
+	0x32, 0x14, 0x2e, 0x42, 0x42, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x50, 0x6c, 0x61,
+	0x79, 0x65, 0x72, 0x52, 0x73, 0x70, 0x52, 0x07, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x42,
+	0x09, 0x0a, 0x07, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x73,
+	0x65, 0x61, 0x74, 0x49, 0x44, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x73, 0x6b, 0x69, 0x70, 0x52, 0x65,
+	0x61, 0x73, 0x6f, 0x6e, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x6e, 0x65, 0x78, 0x74, 0x54, 0x75, 0x72,
+	0x6e, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x61, 0x75, 0x74, 0x6f, 0x4d, 0x6f, 0x76, 0x65, 0x22, 0x29,
+	0x0a, 0x0d, 0x50, 0x6c, 0x61, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x71, 0x12,
+	0x18, 0x0a, 0x07, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x07, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x49, 0x44, 0x22, 0xf5, 0x01, 0x0a, 0x0d, 0x50, 0x6c,
+	0x61, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x73, 0x70, 0x12, 0x1b, 0x0a, 0x06, 0x72,
+	0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x00, 0x52, 0x06, 0x72,
+	0x65, 0x73, 0x75, 0x6c, 0x74, 0x88, 0x01, 0x01, 0x12, 0x1b, 0x0a, 0x06, 0x73, 0x65, 0x61, 0x74,
+	0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x01, 0x52, 0x06, 0x73, 0x65, 0x61, 0x74,
+	0x49, 0x44, 0x88, 0x01, 0x01, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x49, 0x44,
+	0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x49, 0x44, 0x12,
+	0x1f, 0x0a, 0x08, 0x6e, 0x65, 0x78, 0x74, 0x54, 0x75, 0x72, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28,
+	0x0d, 0x48, 0x02, 0x52, 0x08, 0x6e, 0x65, 0x78, 0x74, 0x54, 0x75, 0x72, 0x6e, 0x88, 0x01, 0x01,
+	0x12, 0x1c, 0x0a, 0x09, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x4e, 0x75, 0x6d, 0x18, 0x05, 0x20,
+	0x01, 0x28, 0x0d, 0x52, 0x09, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x4e, 0x75, 0x6d, 0x12, 0x2e,
+	0x0a, 0x07, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32,
+	0x14, 0x2e, 0x42, 0x42, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x50, 0x6c, 0x61, 0x79,
+	0x65, 0x72, 0x52, 0x73, 0x70, 0x52, 0x07, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x42, 0x09,
+	0x0a, 0x07, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x73, 0x65,
+	0x61, 0x74, 0x49, 0x44, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x6e, 0x65, 0x78, 0x74, 0x54, 0x75, 0x72,
+	0x6e, 0x22, 0x23, 0x0a, 0x07, 0x4d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x71, 0x12, 0x18, 0x0a, 0x07,
+	0x70, 0x6c, 0x61, 0x6e, 0x65, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70,
+	0x6c, 0x61, 0x6e, 0x65, 0x49, 0x44, 0x22, 0xe7, 0x03, 0x0a, 0x07, 0x4d, 0x6f, 0x76, 0x65, 0x52,
+	0x73, 0x70, 0x12, 0x1b, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x0d, 0x48, 0x00, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x88, 0x01, 0x01, 0x12,
+	0x1b, 0x0a, 0x06, 0x73, 0x65, 0x61, 0x74, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x48,
+	0x01, 0x52, 0x06, 0x73, 0x65, 0x61, 0x74, 0x49, 0x44, 0x88, 0x01, 0x01, 0x12, 0x18, 0x0a, 0x07,
+	0x70, 0x6c, 0x61, 0x6e, 0x65, 0x49, 0x44, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70,
+	0x6c, 0x61, 0x6e, 0x65, 0x49, 0x44, 0x12, 0x17, 0x0a, 0x04, 0x73, 0x74, 0x65, 0x70, 0x18, 0x04,
+	0x20, 0x01, 0x28, 0x0d, 0x48, 0x02, 0x52, 0x04, 0x73, 0x74, 0x65, 0x70, 0x88, 0x01, 0x01, 0x12,
+	0x25, 0x0a, 0x0b, 0x63, 0x75, 0x72, 0x50, 0x6f, 0x73, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x05,
+	0x20, 0x01, 0x28, 0x0d, 0x48, 0x03, 0x52, 0x0b, 0x63, 0x75, 0x72, 0x50, 0x6f, 0x73, 0x49, 0x6e,
+	0x64, 0x65, 0x78, 0x88, 0x01, 0x01, 0x12, 0x1f, 0x0a, 0x08, 0x6e, 0x65, 0x78, 0x74, 0x54, 0x75,
+	0x72, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x04, 0x52, 0x08, 0x6e, 0x65, 0x78, 0x74,
+	0x54, 0x75, 0x72, 0x6e, 0x88, 0x01, 0x01, 0x12, 0x1b, 0x0a, 0x06, 0x68, 0x61, 0x73, 0x57, 0x69,
+	0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x05, 0x52, 0x06, 0x68, 0x61, 0x73, 0x57, 0x69,
+	0x6e, 0x88, 0x01, 0x01, 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x4e, 0x75,
+	0x6d, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x4e,
+	0x75, 0x6d, 0x12, 0x3b, 0x0a, 0x0b, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x45, 0x76, 0x65, 0x6e,
+	0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x42, 0x42, 0x4d, 0x65, 0x73, 0x73,
+	0x61, 0x67, 0x65, 0x2e, 0x46, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52,
+	0x73, 0x70, 0x52, 0x0b, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12,
+	0x38, 0x0a, 0x0a, 0x74, 0x4b, 0x69, 0x63, 0x6b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x0a, 0x20,
+	0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x42, 0x42, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e,
+	0x54, 0x4b, 0x69, 0x63, 0x6b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x73, 0x70, 0x52, 0x0a, 0x74,
+	0x4b, 0x69, 0x63, 0x6b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x2e, 0x0a, 0x07, 0x70, 0x6c, 0x61,
+	0x79, 0x65, 0x72, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x42, 0x42, 0x4d,
+	0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x52, 0x73, 0x70,
+	0x52, 0x07, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x73, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x72, 0x65,
+	0x73, 0x75, 0x6c, 0x74, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x73, 0x65, 0x61, 0x74, 0x49, 0x44, 0x42,
+	0x07, 0x0a, 0x05, 0x5f, 0x73, 0x74, 0x65, 0x70, 0x42, 0x0e, 0x0a, 0x0c, 0x5f, 0x63, 0x75, 0x72,
+	0x50, 0x6f, 0x73, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x6e, 0x65, 0x78,
+	0x74, 0x54, 0x75, 0x72, 0x6e, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x68, 0x61, 0x73, 0x57, 0x69, 0x6e,
+	0x22, 0x26, 0x0a, 0x0e, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x65, 0x73, 0x68, 0x69, 0x70, 0x52,
+	0x65, 0x71, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x72, 0x75, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28,
+	0x08, 0x52, 0x05, 0x74, 0x72, 0x75, 0x73, 0x74, 0x22, 0x4e, 0x0a, 0x0e, 0x54, 0x72, 0x75, 0x73,
+	0x74, 0x65, 0x65, 0x73, 0x68, 0x69, 0x70, 0x52, 0x73, 0x70, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x72,
+	0x75, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x74, 0x72, 0x75, 0x73, 0x74,
+	0x12, 0x1b, 0x0a, 0x06, 0x73, 0x65, 0x61, 0x74, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d,
+	0x48, 0x00, 0x52, 0x06, 0x73, 0x65, 0x61, 0x74, 0x49, 0x44, 0x88, 0x01, 0x01, 0x42, 0x09, 0x0a,
+	0x07, 0x5f, 0x73, 0x65, 0x61, 0x74, 0x49, 0x44, 0x22, 0x09, 0x0a, 0x07, 0x51, 0x75, 0x69, 0x74,
+	0x52, 0x65, 0x71, 0x22, 0x95, 0x01, 0x0a, 0x07, 0x51, 0x75, 0x69, 0x74, 0x52, 0x73, 0x70, 0x12,
+	0x22, 0x0a, 0x0c, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18,
+	0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x53, 0x74, 0x61,
+	0x74, 0x75, 0x73, 0x12, 0x1b, 0x0a, 0x06, 0x73, 0x65, 0x61, 0x74, 0x49, 0x44, 0x18, 0x02, 0x20,
+	0x01, 0x28, 0x0d, 0x48, 0x00, 0x52, 0x06, 0x73, 0x65, 0x61, 0x74, 0x49, 0x44, 0x88, 0x01, 0x01,
+	0x12, 0x1f, 0x0a, 0x08, 0x6e, 0x65, 0x78, 0x74, 0x54, 0x75, 0x72, 0x6e, 0x18, 0x03, 0x20, 0x01,
+	0x28, 0x0d, 0x48, 0x01, 0x52, 0x08, 0x6e, 0x65, 0x78, 0x74, 0x54, 0x75, 0x72, 0x6e, 0x88, 0x01,
+	0x01, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03,
+	0x75, 0x69, 0x64, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x73, 0x65, 0x61, 0x74, 0x49, 0x44, 0x42, 0x0b,
+	0x0a, 0x09, 0x5f, 0x6e, 0x65, 0x78, 0x74, 0x54, 0x75, 0x72, 0x6e, 0x22, 0x8a, 0x01, 0x0a, 0x0a,
+	0x45, 0x6e, 0x64, 0x47, 0x61, 0x6d, 0x65, 0x52, 0x73, 0x70, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x65,
+	0x61, 0x74, 0x49, 0x44, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0d, 0x52, 0x06, 0x73, 0x65, 0x61, 0x74,
+	0x49, 0x44, 0x12, 0x22, 0x0a, 0x0c, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74,
+	0x75, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x70, 0x6c, 0x61, 0x79, 0x65, 0x72,
+	0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6b, 0x69, 0x63, 0x6b, 0x18, 0x03,
+	0x20, 0x03, 0x28, 0x0d, 0x52, 0x04, 0x6b, 0x69, 0x63, 0x6b, 0x12, 0x16, 0x0a, 0x06, 0x62, 0x65,
+	0x4b, 0x69, 0x63, 0x6b, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0d, 0x52, 0x06, 0x62, 0x65, 0x4b, 0x69,
+	0x63, 0x6b, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x6f, 0x6e, 0x65, 0x79, 0x18, 0x05, 0x20, 0x03, 0x28,
+	0x0d, 0x52, 0x05, 0x6d, 0x6f, 0x6e, 0x65, 0x79, 0x22, 0x14, 0x0a, 0x12, 0x44, 0x69, 0x73, 0x73,
+	0x6f, 0x6c, 0x76, 0x65, 0x54, 0x68, 0x65, 0x47, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x22, 0x14,
+	0x0a, 0x12, 0x44, 0x69, 0x73, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x54, 0x68, 0x65, 0x47, 0x61, 0x6d,
+	0x65, 0x52, 0x73, 0x70, 0x22, 0x2e, 0x0a, 0x0a, 0x50, 0x62, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52,
+	0x73, 0x70, 0x12, 0x20, 0x0a, 0x0b, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x44, 0x61, 0x74,
+	0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
+	0x44, 0x61, 0x74, 0x61, 0x22, 0x10, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x6f, 0x6d, 0x4c,
+	0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x22, 0x28, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x6f,
+	0x6d, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x73, 0x70, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75,
+	0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74,
+	0x22, 0x24, 0x0a, 0x0a, 0x4b, 0x69, 0x63, 0x6b, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x12, 0x16,
+	0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06,
+	0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x22, 0x2c, 0x0a, 0x18, 0x52, 0x6f, 0x6f, 0x6d, 0x43, 0x68,
+	0x61, 0x6e, 0x67, 0x65, 0x4f, 0x66, 0x48, 0x6f, 0x6d, 0x65, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x52,
+	0x73, 0x70, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x03, 0x75, 0x69, 0x64, 0x22, 0x23, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x4d,
+	0x6f, 0x6e, 0x65, 0x79, 0x52, 0x65, 0x71, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x01,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x69, 0x64, 0x22, 0x36, 0x0a, 0x0f, 0x47, 0x65, 0x74,
+	0x55, 0x73, 0x65, 0x72, 0x4d, 0x6f, 0x6e, 0x65, 0x79, 0x52, 0x73, 0x70, 0x12, 0x19, 0x0a, 0x05,
+	0x6d, 0x6f, 0x6e, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x48, 0x00, 0x52, 0x05, 0x6d,
+	0x6f, 0x6e, 0x65, 0x79, 0x88, 0x01, 0x01, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x6d, 0x6f, 0x6e, 0x65,
+	0x79, 0x22, 0x33, 0x0a, 0x07, 0x44, 0x69, 0x73, 0x63, 0x52, 0x65, 0x71, 0x12, 0x10, 0x0a, 0x03,
+	0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x16,
+	0x0a, 0x06, 0x72, 0x6f, 0x6f, 0x6d, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06,
+	0x72, 0x6f, 0x6f, 0x6d, 0x49, 0x64, 0x22, 0x0d, 0x0a, 0x0b, 0x52, 0x6f, 0x6f, 0x6d, 0x51, 0x75,
+	0x69, 0x74, 0x52, 0x65, 0x71, 0x22, 0x10, 0x0a, 0x0e, 0x52, 0x6f, 0x6f, 0x6d, 0x52, 0x65, 0x73,
+	0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x71, 0x22, 0x20, 0x0a, 0x0a, 0x53, 0x65, 0x6e, 0x64, 0x4d,
+	0x73, 0x67, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x32, 0x0a, 0x0a, 0x53, 0x65, 0x6e,
+	0x64, 0x4d, 0x73, 0x67, 0x52, 0x73, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18,
+	0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x10, 0x0a, 0x03, 0x75,
+	0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x69, 0x64, 0x2a, 0xf8, 0x03,
+	0x0a, 0x0a, 0x47, 0x61, 0x6d, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x12, 0x0a, 0x0e,
+	0x47, 0x41, 0x4d, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x4f, 0x4b, 0x10, 0x00,
+	0x12, 0x1b, 0x0a, 0x16, 0x47, 0x41, 0x4d, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f,
+	0x50, 0x4c, 0x41, 0x59, 0x45, 0x52, 0x5f, 0x4e, 0x49, 0x4c, 0x10, 0xe9, 0x07, 0x12, 0x1f, 0x0a,
+	0x1a, 0x47, 0x41, 0x4d, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x49, 0x44,
+	0x5f, 0x50, 0x41, 0x53, 0x53, 0x57, 0x44, 0x5f, 0x4e, 0x49, 0x4c, 0x10, 0xea, 0x07, 0x12, 0x1a,
+	0x0a, 0x15, 0x47, 0x41, 0x4d, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x49,
+	0x44, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0xeb, 0x07, 0x12, 0x1d, 0x0a, 0x18, 0x47, 0x41,
+	0x4d, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x50, 0x41, 0x53, 0x53, 0x57, 0x44,
+	0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0xec, 0x07, 0x12, 0x1e, 0x0a, 0x19, 0x47, 0x41, 0x4d,
+	0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x52, 0x4f, 0x4f, 0x4d, 0x5f, 0x4e, 0x4f,
+	0x54, 0x5f, 0x45, 0x58, 0x49, 0x54, 0x10, 0xed, 0x07, 0x12, 0x17, 0x0a, 0x12, 0x47, 0x41, 0x4d,
+	0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x50, 0x42, 0x5f, 0x45, 0x52, 0x52, 0x10,
+	0xee, 0x07, 0x12, 0x1a, 0x0a, 0x15, 0x47, 0x41, 0x4d, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55,
+	0x53, 0x5f, 0x49, 0x4e, 0x4e, 0x45, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x10, 0xef, 0x07, 0x12, 0x20,
+	0x0a, 0x1b, 0x47, 0x41, 0x4d, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x4c, 0x4f,
+	0x47, 0x49, 0x4e, 0x5f, 0x43, 0x48, 0x45, 0x43, 0x4b, 0x5f, 0x45, 0x52, 0x52, 0x10, 0x9f, 0x08,
+	0x12, 0x13, 0x0a, 0x0f, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x5f, 0x53, 0x74, 0x61, 0x74, 0x75,
+	0x73, 0x5f, 0x30, 0x10, 0x0b, 0x12, 0x13, 0x0a, 0x0f, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x5f,
+	0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x31, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x50, 0x6c,
+	0x61, 0x79, 0x65, 0x72, 0x5f, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x32, 0x10, 0x02, 0x12,
+	0x13, 0x0a, 0x0f, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x5f, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73,
+	0x5f, 0x33, 0x10, 0x03, 0x12, 0x13, 0x0a, 0x0f, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x5f, 0x53,
+	0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x34, 0x10, 0x04, 0x12, 0x13, 0x0a, 0x0f, 0x50, 0x6c, 0x61,
+	0x79, 0x65, 0x72, 0x5f, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x35, 0x10, 0x05, 0x12, 0x13,
+	0x0a, 0x0f, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x5f, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f,
+	0x36, 0x10, 0x06, 0x12, 0x13, 0x0a, 0x0f, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x5f, 0x53, 0x74,
+	0x61, 0x74, 0x75, 0x73, 0x5f, 0x37, 0x10, 0x07, 0x12, 0x13, 0x0a, 0x0f, 0x50, 0x6c, 0x61, 0x79,
+	0x65, 0x72, 0x5f, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x38, 0x10, 0x08, 0x12, 0x13, 0x0a,
+	0x0f, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x5f, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x39,
+	0x10, 0x09, 0x12, 0x14, 0x0a, 0x10, 0x50, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x5f, 0x53, 0x74, 0x61,
+	0x74, 0x75, 0x73, 0x5f, 0x31, 0x30, 0x10, 0x0a, 0x2a, 0x84, 0x01, 0x0a, 0x0a, 0x4b, 0x69, 0x63,
+	0x6b, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x17, 0x0a, 0x13, 0x4b, 0x49, 0x43, 0x4b, 0x5f,
+	0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00,
+	0x12, 0x1f, 0x0a, 0x1b, 0x4b, 0x49, 0x43, 0x4b, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f,
+	0x4c, 0x4f, 0x47, 0x49, 0x4e, 0x5f, 0x45, 0x4c, 0x53, 0x45, 0x57, 0x48, 0x45, 0x52, 0x45, 0x10,
+	0x01, 0x12, 0x21, 0x0a, 0x1d, 0x4b, 0x49, 0x43, 0x4b, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e,
+	0x5f, 0x48, 0x45, 0x41, 0x52, 0x54, 0x42, 0x45, 0x41, 0x54, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x4f,
+	0x55, 0x54, 0x10, 0x02, 0x12, 0x19, 0x0a, 0x15, 0x4b, 0x49, 0x43, 0x4b, 0x5f, 0x52, 0x45, 0x41,
+	0x53, 0x4f, 0x4e, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x4c, 0x4f, 0x47, 0x49, 0x4e, 0x10, 0x03, 0x42,
+	0x0c, 0x5a, 0x0a, 0x2e, 0x2f, 0x3b, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x62, 0x06, 0x70,
+	0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var (
+	file_Message_proto_rawDescOnce sync.Once
+	file_Message_proto_rawDescData = file_Message_proto_rawDesc
+)
+
+func file_Message_proto_rawDescGZIP() []byte {
+	file_Message_proto_rawDescOnce.Do(func() {
+		file_Message_proto_rawDescData = protoimpl.X.CompressGZIP(file_Message_proto_rawDescData)
+	})
+	return file_Message_proto_rawDescData
+}
+
+var file_Message_proto_enumTypes = make([]protoimpl.EnumInfo, 2)
+var file_Message_proto_msgTypes = make([]protoimpl.MessageInfo, 57)
+var file_Message_proto_goTypes = []interface{}{
+	(GameStatus)(0),                  // 0: BBMessage.GameStatus
+	(KickReason)(0),                  // 1: BBMessage.KickReason
+	(*HeartbeatPush)(nil),            // 2: BBMessage.HeartbeatPush
+	(*LoginReq)(nil),                 // 3: BBMessage.LoginReq
+	(*LoginRsp)(nil),                 // 4: BBMessage.LoginRsp
+	(*CreateGameReq)(nil),            // 5: BBMessage.CreateGameReq
+	(*CreateGameRsp)(nil),            // 6: BBMessage.CreateGameRsp
+	(*RoomInfoRsp)(nil),              // 7: BBMessage.RoomInfoRsp
+	(*JoinRoomReq)(nil),              // 8: BBMessage.JoinRoomReq
+	(*RoomKickUserReq)(nil),          // 9: BBMessage.RoomKickUserReq
+	(*RoomKickUserRsp)(nil),          // 10: BBMessage.RoomKickUserRsp
+	(*RoomQuitUserReq)(nil),          // 11: BBMessage.RoomQuitUserReq
+	(*RoomInviteReq)(nil),            // 12: BBMessage.RoomInviteReq
+	(*RoomInviteRsp)(nil),            // 13: BBMessage.RoomInviteRsp
+	(*RoomQuitUserRsp)(nil),          // 14: BBMessage.RoomQuitUserRsp
+	(*JoinRoomInfoRsp)(nil),          // 15: BBMessage.JoinRoomInfoRsp
+	(*RoomInfoReq)(nil),              // 16: BBMessage.RoomInfoReq
+	(*CancelMatchReq)(nil),           // 17: BBMessage.CancelMatchReq
+	(*CancelMatchRsp)(nil),           // 18: BBMessage.CancelMatchRsp
+	(*MatchRsp)(nil),                 // 19: BBMessage.MatchRsp
+	(*MatchJoinUserRsp)(nil),         // 20: BBMessage.MatchJoinUserRsp
+	(*RoomStartGameReq)(nil),         // 21: BBMessage.RoomStartGameReq
+	(*RoomStartGameRsp)(nil),         // 22: BBMessage.RoomStartGameRsp
+	(*GetUserInfoReq)(nil),           // 23: BBMessage.GetUserInfoReq
+	(*KickUserReq)(nil),              // 24: BBMessage.KickUserReq
+	(*GetUserInfoRsp)(nil),           // 25: BBMessage.GetUserInfoRsp
+	(*TKickEventRsp)(nil),            // 26: BBMessage.TKickEventRsp
+	(*KickPlayerRsp)(nil),            // 27: BBMessage.KickPlayerRsp
+	(*FinishEventRsp)(nil),           // 28: BBMessage.FinishEventRsp
+	(*PlayerRsp)(nil),                // 29: BBMessage.PlayerRsp
+	(*PlaneRsp)(nil),                 // 30: BBMessage.PlaneRsp
+	(*RoomDjsRsp)(nil),               // 31: BBMessage.RoomDjsRsp
+	(*RoomJoinUserRsp)(nil),          // 32: BBMessage.RoomJoinUserRsp
+	(*GameStartRsp)(nil),             // 33: BBMessage.GameStartRsp
+	(*ThrowTheDiceReq)(nil),          // 34: BBMessage.ThrowTheDiceReq
+	(*ThrowTheDiceRsp)(nil),          // 35: BBMessage.ThrowTheDiceRsp
+	(*PlaneStartReq)(nil),            // 36: BBMessage.PlaneStartReq
+	(*PlaneStartRsp)(nil),            // 37: BBMessage.PlaneStartRsp
+	(*MoveReq)(nil),                  // 38: BBMessage.MoveReq
+	(*MoveRsp)(nil),                  // 39: BBMessage.MoveRsp
+	(*TrusteeshipReq)(nil),           // 40: BBMessage.TrusteeshipReq
+	(*TrusteeshipRsp)(nil),           // 41: BBMessage.TrusteeshipRsp
+	(*QuitReq)(nil),                  // 42: BBMessage.QuitReq
+	(*QuitRsp)(nil),                  // 43: BBMessage.QuitRsp
+	(*EndGameRsp)(nil),               // 44: BBMessage.EndGameRsp
+	(*DissolveTheGameReq)(nil),       // 45: BBMessage.DissolveTheGameReq
+	(*DissolveTheGameRsp)(nil),       // 46: BBMessage.DissolveTheGameRsp
+	(*PbErrorRsp)(nil),               // 47: BBMessage.PbErrorRsp
+	(*GetRoomListReq)(nil),           // 48: BBMessage.GetRoomListReq
+	(*GetRoomListRsp)(nil),           // 49: BBMessage.GetRoomListRsp
+	(*KickNotify)(nil),               // 50: BBMessage.KickNotify
+	(*RoomChangeOfHomeownerRsp)(nil), // 51: BBMessage.RoomChangeOfHomeownerRsp
+	(*GetUserMoneyReq)(nil),          // 52: BBMessage.GetUserMoneyReq
+	(*GetUserMoneyRsp)(nil),          // 53: BBMessage.GetUserMoneyRsp
+	(*DiscReq)(nil),                  // 54: BBMessage.DiscReq
+	(*RoomQuitReq)(nil),              // 55: BBMessage.RoomQuitReq
+	(*RoomRestartReq)(nil),           // 56: BBMessage.RoomRestartReq
+	(*SendMsgReq)(nil),               // 57: BBMessage.SendMsgReq
+	(*SendMsgRsp)(nil),               // 58: BBMessage.SendMsgRsp
+}
+var file_Message_proto_depIdxs = []int32{
+	27, // 0: BBMessage.TKickEventRsp.kickPlayer:type_name -> BBMessage.KickPlayerRsp
+	30, // 1: BBMessage.PlayerRsp.planes:type_name -> BBMessage.PlaneRsp
+	29, // 2: BBMessage.ThrowTheDiceRsp.players:type_name -> BBMessage.PlayerRsp
+	29, // 3: BBMessage.PlaneStartRsp.players:type_name -> BBMessage.PlayerRsp
+	28, // 4: BBMessage.MoveRsp.finishEvent:type_name -> BBMessage.FinishEventRsp
+	26, // 5: BBMessage.MoveRsp.tKickEvent:type_name -> BBMessage.TKickEventRsp
+	29, // 6: BBMessage.MoveRsp.players:type_name -> BBMessage.PlayerRsp
+	7,  // [7:7] is the sub-list for method output_type
+	7,  // [7:7] is the sub-list for method input_type
+	7,  // [7:7] is the sub-list for extension type_name
+	7,  // [7:7] is the sub-list for extension extendee
+	0,  // [0:7] is the sub-list for field type_name
+}
+
+func init() { file_Message_proto_init() }
+func file_Message_proto_init() {
+	if File_Message_proto != nil {
+		return
+	}
+	if !protoimpl.UnsafeEnabled {
+		file_Message_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*HeartbeatPush); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_Message_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*LoginReq); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_Message_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*LoginRsp); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_Message_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*CreateGameReq); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_Message_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*CreateGameRsp); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_Message_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*RoomInfoRsp); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_Message_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*JoinRoomReq); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_Message_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*RoomKickUserReq); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_Message_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*RoomKickUserRsp); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_Message_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*RoomQuitUserReq); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_Message_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*RoomInviteReq); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_Message_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*RoomInviteRsp); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_Message_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*RoomQuitUserRsp); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_Message_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*JoinRoomInfoRsp); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_Message_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*RoomInfoReq); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_Message_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*CancelMatchReq); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_Message_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*CancelMatchRsp); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_Message_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*MatchRsp); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_Message_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*MatchJoinUserRsp); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_Message_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*RoomStartGameReq); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_Message_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*RoomStartGameRsp); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_Message_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GetUserInfoReq); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_Message_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*KickUserReq); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_Message_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GetUserInfoRsp); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_Message_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*TKickEventRsp); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_Message_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*KickPlayerRsp); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_Message_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*FinishEventRsp); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_Message_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*PlayerRsp); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_Message_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*PlaneRsp); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_Message_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*RoomDjsRsp); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_Message_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*RoomJoinUserRsp); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_Message_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GameStartRsp); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_Message_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ThrowTheDiceReq); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_Message_proto_msgTypes[33].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ThrowTheDiceRsp); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_Message_proto_msgTypes[34].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*PlaneStartReq); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_Message_proto_msgTypes[35].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*PlaneStartRsp); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_Message_proto_msgTypes[36].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*MoveReq); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_Message_proto_msgTypes[37].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*MoveRsp); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_Message_proto_msgTypes[38].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*TrusteeshipReq); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_Message_proto_msgTypes[39].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*TrusteeshipRsp); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_Message_proto_msgTypes[40].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*QuitReq); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_Message_proto_msgTypes[41].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*QuitRsp); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_Message_proto_msgTypes[42].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*EndGameRsp); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_Message_proto_msgTypes[43].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*DissolveTheGameReq); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_Message_proto_msgTypes[44].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*DissolveTheGameRsp); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_Message_proto_msgTypes[45].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*PbErrorRsp); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_Message_proto_msgTypes[46].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GetRoomListReq); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_Message_proto_msgTypes[47].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GetRoomListRsp); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_Message_proto_msgTypes[48].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*KickNotify); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_Message_proto_msgTypes[49].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*RoomChangeOfHomeownerRsp); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_Message_proto_msgTypes[50].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GetUserMoneyReq); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_Message_proto_msgTypes[51].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GetUserMoneyRsp); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_Message_proto_msgTypes[52].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*DiscReq); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_Message_proto_msgTypes[53].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*RoomQuitReq); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_Message_proto_msgTypes[54].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*RoomRestartReq); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_Message_proto_msgTypes[55].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*SendMsgReq); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_Message_proto_msgTypes[56].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*SendMsgRsp); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+	}
+	file_Message_proto_msgTypes[3].OneofWrappers = []interface{}{}
+	file_Message_proto_msgTypes[4].OneofWrappers = []interface{}{}
+	file_Message_proto_msgTypes[5].OneofWrappers = []interface{}{}
+	file_Message_proto_msgTypes[6].OneofWrappers = []interface{}{}
+	file_Message_proto_msgTypes[10].OneofWrappers = []interface{}{}
+	file_Message_proto_msgTypes[11].OneofWrappers = []interface{}{}
+	file_Message_proto_msgTypes[13].OneofWrappers = []interface{}{}
+	file_Message_proto_msgTypes[14].OneofWrappers = []interface{}{}
+	file_Message_proto_msgTypes[16].OneofWrappers = []interface{}{}
+	file_Message_proto_msgTypes[17].OneofWrappers = []interface{}{}
+	file_Message_proto_msgTypes[18].OneofWrappers = []interface{}{}
+	file_Message_proto_msgTypes[23].OneofWrappers = []interface{}{}
+	file_Message_proto_msgTypes[24].OneofWrappers = []interface{}{}
+	file_Message_proto_msgTypes[25].OneofWrappers = []interface{}{}
+	file_Message_proto_msgTypes[26].OneofWrappers = []interface{}{}
+	file_Message_proto_msgTypes[27].OneofWrappers = []interface{}{}
+	file_Message_proto_msgTypes[28].OneofWrappers = []interface{}{}
+	file_Message_proto_msgTypes[29].OneofWrappers = []interface{}{}
+	file_Message_proto_msgTypes[30].OneofWrappers = []interface{}{}
+	file_Message_proto_msgTypes[31].OneofWrappers = []interface{}{}
+	file_Message_proto_msgTypes[33].OneofWrappers = []interface{}{}
+	file_Message_proto_msgTypes[35].OneofWrappers = []interface{}{}
+	file_Message_proto_msgTypes[37].OneofWrappers = []interface{}{}
+	file_Message_proto_msgTypes[39].OneofWrappers = []interface{}{}
+	file_Message_proto_msgTypes[41].OneofWrappers = []interface{}{}
+	file_Message_proto_msgTypes[51].OneofWrappers = []interface{}{}
+	type x struct{}
+	out := protoimpl.TypeBuilder{
+		File: protoimpl.DescBuilder{
+			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+			RawDescriptor: file_Message_proto_rawDesc,
+			NumEnums:      2,
+			NumMessages:   57,
+			NumExtensions: 0,
+			NumServices:   0,
+		},
+		GoTypes:           file_Message_proto_goTypes,
+		DependencyIndexes: file_Message_proto_depIdxs,
+		EnumInfos:         file_Message_proto_enumTypes,
+		MessageInfos:      file_Message_proto_msgTypes,
+	}.Build()
+	File_Message_proto = out.File
+	file_Message_proto_rawDesc = nil
+	file_Message_proto_goTypes = nil
+	file_Message_proto_depIdxs = nil
+}

+ 362 - 0
Server/Message/MessageID.pb.go

@@ -0,0 +1,362 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// 	protoc-gen-go v1.26.0
+// 	protoc        v4.25.1
+// source: MessageID.proto
+
+package message
+
+import (
+	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+	reflect "reflect"
+	sync "sync"
+)
+
+const (
+	// Verify that this generated code is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+	// Verify that runtime/protoimpl is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+type MSGID int32
+
+const (
+	MSGID_MSGID_None           MSGID = 0
+	MSGID_MSGID_Heartbeat_Push MSGID = 1  // 心跳
+	MSGID_MSGID_Login          MSGID = 2  // 登录
+	MSGID_MSGID_Get_Room_List  MSGID = 10 // 拉取房间列表
+	// c-s
+	MSGID_Get_User_Info_Req MSGID = 3 //获取用户信息
+	// Get_User_Info_Req2 = 31 ;   //获取用户新信息
+	MSGID_Throw_The_Dice_Req  MSGID = 5  //客户端请求掷子,空消息
+	MSGID_Start_Plane_Req     MSGID = 9  //客户端请求起飞
+	MSGID_Move_Req            MSGID = 6  //客户端请求行走
+	MSGID_Trusteeship_Req     MSGID = 14 //客户端请求托管
+	MSGID_Quit_Req            MSGID = 16 //客户端请求退出游戏
+	MSGID_Create_Game_Req     MSGID = 23 //客户端请求创建游戏房间
+	MSGID_Join_Room_Req       MSGID = 26 //客户端请求加入游戏房间
+	MSGID_Room_Start_Game_Req MSGID = 27 //客户端请求开始游戏
+	MSGID_Room_Quit_Req       MSGID = 33 //客户端请求退出游戏房间
+	MSGID_Room_Kick_User_Req  MSGID = 44 //客户端请求踢人
+	MSGID_Room_Invite_Req     MSGID = 48 //客户端邀请玩家
+	MSGID_Room_Info_Req       MSGID = 46 //客户端请求获取房间信息
+	MSGID_Cancel_Match_Req    MSGID = 45 //客户端请求取消匹配
+	MSGID_Room_Restart_Req    MSGID = 51 //客户端请求再来一局
+	MSGID_Disc_Req            MSGID = 54 //客户端请求语聊房小圆盘
+	// START_GAME = 11 ;   // 拉取房间列表
+	MSGID_MSGID_Kick_Notify     MSGID = 1001 // 踢人通知
+	MSGID_Dissolve_The_Game_Req MSGID = 56   //房主请求解散游戏
+	MSGID_Close_Game_Req        MSGID = 58   //客户端请求关闭游戏
+	MSGID_Get_User_Money_Req    MSGID = 60   //客户端请求获取游戏金币
+	MSGID_Send_Msg_Req          MSGID = 62   //客户端请求发送消息
+	// s-c
+	MSGID_Get_User_Info_Rsp     MSGID = 13 //通知获取玩家信息
+	MSGID_Join_Room_Info_Rsp    MSGID = 19 //通知客户端加入新玩家
+	MSGID_Start_Game_Rsp        MSGID = 4  //通知开始游戏并且开始掷子
+	MSGID_Throw_The_Dice_Rsp    MSGID = 8  //通知筛子结果
+	MSGID_Start_Plane_Rsp       MSGID = 11 //通知起飞结果
+	MSGID_Move_Rsp              MSGID = 12 //通知移动结果
+	MSGID_Trusteeship_Rsp       MSGID = 15 //通知玩家托管结果
+	MSGID_Eng_Game_Rsp          MSGID = 17 //通知玩家结束游戏
+	MSGID_Quit_Rsq              MSGID = 18 //通知客户端退出游戏
+	MSGID_Dissolve_The_Game_Rsp MSGID = 20 //20解散游戏
+	MSGID_Cancel_Match_Rsp      MSGID = 47 //通知客户端取消匹配
+	MSGID_Room_Start_Game_Rsp   MSGID = 21 //通知客户端开始游戏
+	MSGID_Room_Info_Rsp         MSGID = 25 //通知客户端房间玩家信息
+	MSGID_Room_Join_User_Rsp    MSGID = 22 //通知客户端加入新玩家
+	// Match_Join_User_Rsp = 30 ;   //通知客户端的匹配界面加入新玩家
+	MSGID_Room_Kick_User_Rsp           MSGID = 24 //通知客户端踢人
+	MSGID_Create_Game_Rsp              MSGID = 28 //通知客户端创建游戏房间
+	MSGID_Create_Game_Error_Rsp        MSGID = 34 //通知客户端建房或者加入房间失败失败,当前用户已有游戏房间
+	MSGID_Pb_Error_Rsp                 MSGID = 50 //通知客户端pb解析错误
+	MSGID_Move_Error_Rsp               MSGID = 29 //通知到客户端行走出错
+	MSGID_Room_Quit_Rsp                MSGID = 32 //通知客户端退出游戏房间 或者解散房间
+	MSGID_Room_Dissolution_Rsp         MSGID = 35 //通知客户端解散游戏房间
+	MSGID_Room_Invite_Rsp              MSGID = 49 //通知客户端邀请结果
+	MSGID_Match_Rsp                    MSGID = 52 //通知客户端匹配结果
+	MSGID_Room_Change_Of_Homeowner_Rsp MSGID = 53 //通知客户端房主变更
+	MSGID_Disc_Rsp                     MSGID = 55 //通知客户端小圆盘状态
+	MSGID_Room_Djs_Rsp                 MSGID = 57 //通知匹配倒计时
+	MSGID_Close_Game_Rsp               MSGID = 59 //客户端请求关闭游戏
+	MSGID_Get_User_Money_Rsp           MSGID = 61 //客户端请求获取游戏金币
+	MSGID_Send_Msg_Rsp                 MSGID = 63 //通知客户端发送消息
+	MSGID_MSGID_Heartbeat_Push_Rsp     MSGID = 64 // 心跳
+)
+
+// Enum value maps for MSGID.
+var (
+	MSGID_name = map[int32]string{
+		0:    "MSGID_None",
+		1:    "MSGID_Heartbeat_Push",
+		2:    "MSGID_Login",
+		10:   "MSGID_Get_Room_List",
+		3:    "Get_User_Info_Req",
+		5:    "Throw_The_Dice_Req",
+		9:    "Start_Plane_Req",
+		6:    "Move_Req",
+		14:   "Trusteeship_Req",
+		16:   "Quit_Req",
+		23:   "Create_Game_Req",
+		26:   "Join_Room_Req",
+		27:   "Room_Start_Game_Req",
+		33:   "Room_Quit_Req",
+		44:   "Room_Kick_User_Req",
+		48:   "Room_Invite_Req",
+		46:   "Room_Info_Req",
+		45:   "Cancel_Match_Req",
+		51:   "Room_Restart_Req",
+		54:   "Disc_Req",
+		1001: "MSGID_Kick_Notify",
+		56:   "Dissolve_The_Game_Req",
+		58:   "Close_Game_Req",
+		60:   "Get_User_Money_Req",
+		62:   "Send_Msg_Req",
+		13:   "Get_User_Info_Rsp",
+		19:   "Join_Room_Info_Rsp",
+		4:    "Start_Game_Rsp",
+		8:    "Throw_The_Dice_Rsp",
+		11:   "Start_Plane_Rsp",
+		12:   "Move_Rsp",
+		15:   "Trusteeship_Rsp",
+		17:   "Eng_Game_Rsp",
+		18:   "Quit_Rsq",
+		20:   "Dissolve_The_Game_Rsp",
+		47:   "Cancel_Match_Rsp",
+		21:   "Room_Start_Game_Rsp",
+		25:   "Room_Info_Rsp",
+		22:   "Room_Join_User_Rsp",
+		24:   "Room_Kick_User_Rsp",
+		28:   "Create_Game_Rsp",
+		34:   "Create_Game_Error_Rsp",
+		50:   "Pb_Error_Rsp",
+		29:   "Move_Error_Rsp",
+		32:   "Room_Quit_Rsp",
+		35:   "Room_Dissolution_Rsp",
+		49:   "Room_Invite_Rsp",
+		52:   "Match_Rsp",
+		53:   "Room_Change_Of_Homeowner_Rsp",
+		55:   "Disc_Rsp",
+		57:   "Room_Djs_Rsp",
+		59:   "Close_Game_Rsp",
+		61:   "Get_User_Money_Rsp",
+		63:   "Send_Msg_Rsp",
+		64:   "MSGID_Heartbeat_Push_Rsp",
+	}
+	MSGID_value = map[string]int32{
+		"MSGID_None":                   0,
+		"MSGID_Heartbeat_Push":         1,
+		"MSGID_Login":                  2,
+		"MSGID_Get_Room_List":          10,
+		"Get_User_Info_Req":            3,
+		"Throw_The_Dice_Req":           5,
+		"Start_Plane_Req":              9,
+		"Move_Req":                     6,
+		"Trusteeship_Req":              14,
+		"Quit_Req":                     16,
+		"Create_Game_Req":              23,
+		"Join_Room_Req":                26,
+		"Room_Start_Game_Req":          27,
+		"Room_Quit_Req":                33,
+		"Room_Kick_User_Req":           44,
+		"Room_Invite_Req":              48,
+		"Room_Info_Req":                46,
+		"Cancel_Match_Req":             45,
+		"Room_Restart_Req":             51,
+		"Disc_Req":                     54,
+		"MSGID_Kick_Notify":            1001,
+		"Dissolve_The_Game_Req":        56,
+		"Close_Game_Req":               58,
+		"Get_User_Money_Req":           60,
+		"Send_Msg_Req":                 62,
+		"Get_User_Info_Rsp":            13,
+		"Join_Room_Info_Rsp":           19,
+		"Start_Game_Rsp":               4,
+		"Throw_The_Dice_Rsp":           8,
+		"Start_Plane_Rsp":              11,
+		"Move_Rsp":                     12,
+		"Trusteeship_Rsp":              15,
+		"Eng_Game_Rsp":                 17,
+		"Quit_Rsq":                     18,
+		"Dissolve_The_Game_Rsp":        20,
+		"Cancel_Match_Rsp":             47,
+		"Room_Start_Game_Rsp":          21,
+		"Room_Info_Rsp":                25,
+		"Room_Join_User_Rsp":           22,
+		"Room_Kick_User_Rsp":           24,
+		"Create_Game_Rsp":              28,
+		"Create_Game_Error_Rsp":        34,
+		"Pb_Error_Rsp":                 50,
+		"Move_Error_Rsp":               29,
+		"Room_Quit_Rsp":                32,
+		"Room_Dissolution_Rsp":         35,
+		"Room_Invite_Rsp":              49,
+		"Match_Rsp":                    52,
+		"Room_Change_Of_Homeowner_Rsp": 53,
+		"Disc_Rsp":                     55,
+		"Room_Djs_Rsp":                 57,
+		"Close_Game_Rsp":               59,
+		"Get_User_Money_Rsp":           61,
+		"Send_Msg_Rsp":                 63,
+		"MSGID_Heartbeat_Push_Rsp":     64,
+	}
+)
+
+func (x MSGID) Enum() *MSGID {
+	p := new(MSGID)
+	*p = x
+	return p
+}
+
+func (x MSGID) String() string {
+	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (MSGID) Descriptor() protoreflect.EnumDescriptor {
+	return file_MessageID_proto_enumTypes[0].Descriptor()
+}
+
+func (MSGID) Type() protoreflect.EnumType {
+	return &file_MessageID_proto_enumTypes[0]
+}
+
+func (x MSGID) Number() protoreflect.EnumNumber {
+	return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use MSGID.Descriptor instead.
+func (MSGID) EnumDescriptor() ([]byte, []int) {
+	return file_MessageID_proto_rawDescGZIP(), []int{0}
+}
+
+var File_MessageID_proto protoreflect.FileDescriptor
+
+var file_MessageID_proto_rawDesc = []byte{
+	0x0a, 0x0f, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x49, 0x44, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+	0x6f, 0x12, 0x09, 0x42, 0x42, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2a, 0x94, 0x09, 0x0a,
+	0x05, 0x4d, 0x53, 0x47, 0x49, 0x44, 0x12, 0x0e, 0x0a, 0x0a, 0x4d, 0x53, 0x47, 0x49, 0x44, 0x5f,
+	0x4e, 0x6f, 0x6e, 0x65, 0x10, 0x00, 0x12, 0x18, 0x0a, 0x14, 0x4d, 0x53, 0x47, 0x49, 0x44, 0x5f,
+	0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x5f, 0x50, 0x75, 0x73, 0x68, 0x10, 0x01,
+	0x12, 0x0f, 0x0a, 0x0b, 0x4d, 0x53, 0x47, 0x49, 0x44, 0x5f, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x10,
+	0x02, 0x12, 0x17, 0x0a, 0x13, 0x4d, 0x53, 0x47, 0x49, 0x44, 0x5f, 0x47, 0x65, 0x74, 0x5f, 0x52,
+	0x6f, 0x6f, 0x6d, 0x5f, 0x4c, 0x69, 0x73, 0x74, 0x10, 0x0a, 0x12, 0x15, 0x0a, 0x11, 0x47, 0x65,
+	0x74, 0x5f, 0x55, 0x73, 0x65, 0x72, 0x5f, 0x49, 0x6e, 0x66, 0x6f, 0x5f, 0x52, 0x65, 0x71, 0x10,
+	0x03, 0x12, 0x16, 0x0a, 0x12, 0x54, 0x68, 0x72, 0x6f, 0x77, 0x5f, 0x54, 0x68, 0x65, 0x5f, 0x44,
+	0x69, 0x63, 0x65, 0x5f, 0x52, 0x65, 0x71, 0x10, 0x05, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x74, 0x61,
+	0x72, 0x74, 0x5f, 0x50, 0x6c, 0x61, 0x6e, 0x65, 0x5f, 0x52, 0x65, 0x71, 0x10, 0x09, 0x12, 0x0c,
+	0x0a, 0x08, 0x4d, 0x6f, 0x76, 0x65, 0x5f, 0x52, 0x65, 0x71, 0x10, 0x06, 0x12, 0x13, 0x0a, 0x0f,
+	0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x65, 0x73, 0x68, 0x69, 0x70, 0x5f, 0x52, 0x65, 0x71, 0x10,
+	0x0e, 0x12, 0x0c, 0x0a, 0x08, 0x51, 0x75, 0x69, 0x74, 0x5f, 0x52, 0x65, 0x71, 0x10, 0x10, 0x12,
+	0x13, 0x0a, 0x0f, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x47, 0x61, 0x6d, 0x65, 0x5f, 0x52,
+	0x65, 0x71, 0x10, 0x17, 0x12, 0x11, 0x0a, 0x0d, 0x4a, 0x6f, 0x69, 0x6e, 0x5f, 0x52, 0x6f, 0x6f,
+	0x6d, 0x5f, 0x52, 0x65, 0x71, 0x10, 0x1a, 0x12, 0x17, 0x0a, 0x13, 0x52, 0x6f, 0x6f, 0x6d, 0x5f,
+	0x53, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x47, 0x61, 0x6d, 0x65, 0x5f, 0x52, 0x65, 0x71, 0x10, 0x1b,
+	0x12, 0x11, 0x0a, 0x0d, 0x52, 0x6f, 0x6f, 0x6d, 0x5f, 0x51, 0x75, 0x69, 0x74, 0x5f, 0x52, 0x65,
+	0x71, 0x10, 0x21, 0x12, 0x16, 0x0a, 0x12, 0x52, 0x6f, 0x6f, 0x6d, 0x5f, 0x4b, 0x69, 0x63, 0x6b,
+	0x5f, 0x55, 0x73, 0x65, 0x72, 0x5f, 0x52, 0x65, 0x71, 0x10, 0x2c, 0x12, 0x13, 0x0a, 0x0f, 0x52,
+	0x6f, 0x6f, 0x6d, 0x5f, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x5f, 0x52, 0x65, 0x71, 0x10, 0x30,
+	0x12, 0x11, 0x0a, 0x0d, 0x52, 0x6f, 0x6f, 0x6d, 0x5f, 0x49, 0x6e, 0x66, 0x6f, 0x5f, 0x52, 0x65,
+	0x71, 0x10, 0x2e, 0x12, 0x14, 0x0a, 0x10, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x5f, 0x4d, 0x61,
+	0x74, 0x63, 0x68, 0x5f, 0x52, 0x65, 0x71, 0x10, 0x2d, 0x12, 0x14, 0x0a, 0x10, 0x52, 0x6f, 0x6f,
+	0x6d, 0x5f, 0x52, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x52, 0x65, 0x71, 0x10, 0x33, 0x12,
+	0x0c, 0x0a, 0x08, 0x44, 0x69, 0x73, 0x63, 0x5f, 0x52, 0x65, 0x71, 0x10, 0x36, 0x12, 0x16, 0x0a,
+	0x11, 0x4d, 0x53, 0x47, 0x49, 0x44, 0x5f, 0x4b, 0x69, 0x63, 0x6b, 0x5f, 0x4e, 0x6f, 0x74, 0x69,
+	0x66, 0x79, 0x10, 0xe9, 0x07, 0x12, 0x19, 0x0a, 0x15, 0x44, 0x69, 0x73, 0x73, 0x6f, 0x6c, 0x76,
+	0x65, 0x5f, 0x54, 0x68, 0x65, 0x5f, 0x47, 0x61, 0x6d, 0x65, 0x5f, 0x52, 0x65, 0x71, 0x10, 0x38,
+	0x12, 0x12, 0x0a, 0x0e, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x5f, 0x47, 0x61, 0x6d, 0x65, 0x5f, 0x52,
+	0x65, 0x71, 0x10, 0x3a, 0x12, 0x16, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x5f, 0x55, 0x73, 0x65, 0x72,
+	0x5f, 0x4d, 0x6f, 0x6e, 0x65, 0x79, 0x5f, 0x52, 0x65, 0x71, 0x10, 0x3c, 0x12, 0x10, 0x0a, 0x0c,
+	0x53, 0x65, 0x6e, 0x64, 0x5f, 0x4d, 0x73, 0x67, 0x5f, 0x52, 0x65, 0x71, 0x10, 0x3e, 0x12, 0x15,
+	0x0a, 0x11, 0x47, 0x65, 0x74, 0x5f, 0x55, 0x73, 0x65, 0x72, 0x5f, 0x49, 0x6e, 0x66, 0x6f, 0x5f,
+	0x52, 0x73, 0x70, 0x10, 0x0d, 0x12, 0x16, 0x0a, 0x12, 0x4a, 0x6f, 0x69, 0x6e, 0x5f, 0x52, 0x6f,
+	0x6f, 0x6d, 0x5f, 0x49, 0x6e, 0x66, 0x6f, 0x5f, 0x52, 0x73, 0x70, 0x10, 0x13, 0x12, 0x12, 0x0a,
+	0x0e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x47, 0x61, 0x6d, 0x65, 0x5f, 0x52, 0x73, 0x70, 0x10,
+	0x04, 0x12, 0x16, 0x0a, 0x12, 0x54, 0x68, 0x72, 0x6f, 0x77, 0x5f, 0x54, 0x68, 0x65, 0x5f, 0x44,
+	0x69, 0x63, 0x65, 0x5f, 0x52, 0x73, 0x70, 0x10, 0x08, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x74, 0x61,
+	0x72, 0x74, 0x5f, 0x50, 0x6c, 0x61, 0x6e, 0x65, 0x5f, 0x52, 0x73, 0x70, 0x10, 0x0b, 0x12, 0x0c,
+	0x0a, 0x08, 0x4d, 0x6f, 0x76, 0x65, 0x5f, 0x52, 0x73, 0x70, 0x10, 0x0c, 0x12, 0x13, 0x0a, 0x0f,
+	0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x65, 0x73, 0x68, 0x69, 0x70, 0x5f, 0x52, 0x73, 0x70, 0x10,
+	0x0f, 0x12, 0x10, 0x0a, 0x0c, 0x45, 0x6e, 0x67, 0x5f, 0x47, 0x61, 0x6d, 0x65, 0x5f, 0x52, 0x73,
+	0x70, 0x10, 0x11, 0x12, 0x0c, 0x0a, 0x08, 0x51, 0x75, 0x69, 0x74, 0x5f, 0x52, 0x73, 0x71, 0x10,
+	0x12, 0x12, 0x19, 0x0a, 0x15, 0x44, 0x69, 0x73, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x5f, 0x54, 0x68,
+	0x65, 0x5f, 0x47, 0x61, 0x6d, 0x65, 0x5f, 0x52, 0x73, 0x70, 0x10, 0x14, 0x12, 0x14, 0x0a, 0x10,
+	0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x5f, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x52, 0x73, 0x70,
+	0x10, 0x2f, 0x12, 0x17, 0x0a, 0x13, 0x52, 0x6f, 0x6f, 0x6d, 0x5f, 0x53, 0x74, 0x61, 0x72, 0x74,
+	0x5f, 0x47, 0x61, 0x6d, 0x65, 0x5f, 0x52, 0x73, 0x70, 0x10, 0x15, 0x12, 0x11, 0x0a, 0x0d, 0x52,
+	0x6f, 0x6f, 0x6d, 0x5f, 0x49, 0x6e, 0x66, 0x6f, 0x5f, 0x52, 0x73, 0x70, 0x10, 0x19, 0x12, 0x16,
+	0x0a, 0x12, 0x52, 0x6f, 0x6f, 0x6d, 0x5f, 0x4a, 0x6f, 0x69, 0x6e, 0x5f, 0x55, 0x73, 0x65, 0x72,
+	0x5f, 0x52, 0x73, 0x70, 0x10, 0x16, 0x12, 0x16, 0x0a, 0x12, 0x52, 0x6f, 0x6f, 0x6d, 0x5f, 0x4b,
+	0x69, 0x63, 0x6b, 0x5f, 0x55, 0x73, 0x65, 0x72, 0x5f, 0x52, 0x73, 0x70, 0x10, 0x18, 0x12, 0x13,
+	0x0a, 0x0f, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x47, 0x61, 0x6d, 0x65, 0x5f, 0x52, 0x73,
+	0x70, 0x10, 0x1c, 0x12, 0x19, 0x0a, 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x47, 0x61,
+	0x6d, 0x65, 0x5f, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x52, 0x73, 0x70, 0x10, 0x22, 0x12, 0x10,
+	0x0a, 0x0c, 0x50, 0x62, 0x5f, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x52, 0x73, 0x70, 0x10, 0x32,
+	0x12, 0x12, 0x0a, 0x0e, 0x4d, 0x6f, 0x76, 0x65, 0x5f, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x52,
+	0x73, 0x70, 0x10, 0x1d, 0x12, 0x11, 0x0a, 0x0d, 0x52, 0x6f, 0x6f, 0x6d, 0x5f, 0x51, 0x75, 0x69,
+	0x74, 0x5f, 0x52, 0x73, 0x70, 0x10, 0x20, 0x12, 0x18, 0x0a, 0x14, 0x52, 0x6f, 0x6f, 0x6d, 0x5f,
+	0x44, 0x69, 0x73, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x52, 0x73, 0x70, 0x10,
+	0x23, 0x12, 0x13, 0x0a, 0x0f, 0x52, 0x6f, 0x6f, 0x6d, 0x5f, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65,
+	0x5f, 0x52, 0x73, 0x70, 0x10, 0x31, 0x12, 0x0d, 0x0a, 0x09, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x5f,
+	0x52, 0x73, 0x70, 0x10, 0x34, 0x12, 0x20, 0x0a, 0x1c, 0x52, 0x6f, 0x6f, 0x6d, 0x5f, 0x43, 0x68,
+	0x61, 0x6e, 0x67, 0x65, 0x5f, 0x4f, 0x66, 0x5f, 0x48, 0x6f, 0x6d, 0x65, 0x6f, 0x77, 0x6e, 0x65,
+	0x72, 0x5f, 0x52, 0x73, 0x70, 0x10, 0x35, 0x12, 0x0c, 0x0a, 0x08, 0x44, 0x69, 0x73, 0x63, 0x5f,
+	0x52, 0x73, 0x70, 0x10, 0x37, 0x12, 0x10, 0x0a, 0x0c, 0x52, 0x6f, 0x6f, 0x6d, 0x5f, 0x44, 0x6a,
+	0x73, 0x5f, 0x52, 0x73, 0x70, 0x10, 0x39, 0x12, 0x12, 0x0a, 0x0e, 0x43, 0x6c, 0x6f, 0x73, 0x65,
+	0x5f, 0x47, 0x61, 0x6d, 0x65, 0x5f, 0x52, 0x73, 0x70, 0x10, 0x3b, 0x12, 0x16, 0x0a, 0x12, 0x47,
+	0x65, 0x74, 0x5f, 0x55, 0x73, 0x65, 0x72, 0x5f, 0x4d, 0x6f, 0x6e, 0x65, 0x79, 0x5f, 0x52, 0x73,
+	0x70, 0x10, 0x3d, 0x12, 0x10, 0x0a, 0x0c, 0x53, 0x65, 0x6e, 0x64, 0x5f, 0x4d, 0x73, 0x67, 0x5f,
+	0x52, 0x73, 0x70, 0x10, 0x3f, 0x12, 0x1c, 0x0a, 0x18, 0x4d, 0x53, 0x47, 0x49, 0x44, 0x5f, 0x48,
+	0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x5f, 0x50, 0x75, 0x73, 0x68, 0x5f, 0x52, 0x73,
+	0x70, 0x10, 0x40, 0x42, 0x0c, 0x5a, 0x0a, 0x2e, 0x2f, 0x3b, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67,
+	0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var (
+	file_MessageID_proto_rawDescOnce sync.Once
+	file_MessageID_proto_rawDescData = file_MessageID_proto_rawDesc
+)
+
+func file_MessageID_proto_rawDescGZIP() []byte {
+	file_MessageID_proto_rawDescOnce.Do(func() {
+		file_MessageID_proto_rawDescData = protoimpl.X.CompressGZIP(file_MessageID_proto_rawDescData)
+	})
+	return file_MessageID_proto_rawDescData
+}
+
+var file_MessageID_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
+var file_MessageID_proto_goTypes = []interface{}{
+	(MSGID)(0), // 0: BBMessage.MSGID
+}
+var file_MessageID_proto_depIdxs = []int32{
+	0, // [0:0] is the sub-list for method output_type
+	0, // [0:0] is the sub-list for method input_type
+	0, // [0:0] is the sub-list for extension type_name
+	0, // [0:0] is the sub-list for extension extendee
+	0, // [0:0] is the sub-list for field type_name
+}
+
+func init() { file_MessageID_proto_init() }
+func file_MessageID_proto_init() {
+	if File_MessageID_proto != nil {
+		return
+	}
+	type x struct{}
+	out := protoimpl.TypeBuilder{
+		File: protoimpl.DescBuilder{
+			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+			RawDescriptor: file_MessageID_proto_rawDesc,
+			NumEnums:      1,
+			NumMessages:   0,
+			NumExtensions: 0,
+			NumServices:   0,
+		},
+		GoTypes:           file_MessageID_proto_goTypes,
+		DependencyIndexes: file_MessageID_proto_depIdxs,
+		EnumInfos:         file_MessageID_proto_enumTypes,
+	}.Build()
+	File_MessageID_proto = out.File
+	file_MessageID_proto_rawDesc = nil
+	file_MessageID_proto_goTypes = nil
+	file_MessageID_proto_depIdxs = nil
+}

+ 27 - 0
Server/Scheme/SchemeDef.go

@@ -0,0 +1,27 @@
+package scheme
+
+type ID int32
+type G int32
+
+const (
+	ID_Min = iota
+	ID_Item
+	ID_Level
+	ID_Role
+	ID_RoleLevel
+	ID_Sz
+	ID_Max
+)
+
+type Scp interface {
+	Load()
+	Get(key int32) (interface{}, error)
+}
+
+func Register() {
+	mgr.schemeList[ID_Item] = new(Item)
+	mgr.schemeList[ID_Level] = new(Level)
+	mgr.schemeList[ID_Role] = new(Role)
+	mgr.schemeList[ID_RoleLevel] = new(RoleLevel)
+	mgr.schemeList[ID_Sz] = new(Sz)
+}

+ 89 - 0
Server/Scheme/SchemeItem.go

@@ -0,0 +1,89 @@
+package scheme
+
+import (
+	"Server-Core/Server/Base"
+	"errors"
+	"fmt"
+	"net"
+	"reflect"
+	"strconv"
+)
+
+type ItemItem struct {
+	Id      int32
+	Quality int32
+	Price   int32
+	Type    string
+	Value   int32
+}
+
+type Item struct {
+	dataList map[int32]*ItemItem
+}
+
+var ip string = ""
+
+func getIp() string {
+
+	addrList, err := net.InterfaceAddrs()
+	if err != nil {
+		panic(err)
+	}
+	for _, address := range addrList {
+		if ipNet, ok := address.(*net.IPNet); ok && !ipNet.IP.IsLoopback() {
+			if ipNet.IP.To4() != nil {
+				fmt.Println(ipNet.IP.String())
+				ip = ipNet.IP.String()
+				break
+			}
+		}
+	}
+	return ip
+}
+
+func (scp *Item) Load() {
+	scp.dataList = make(map[int32]*ItemItem)
+	getIp()
+	fmt.Printf("exPath", ip)
+	//records := base.LoadCsvCfg("../Scp/Item.csv").Records
+	//records := base.LoadCsvCfg("../Scp/Item.csv").Records
+	//records := base.LoadCsvCfg("./Scp/Item.csv").Records
+	var path string = ""
+	if ip == "192.168.1.122" {
+		path = "E://ChatGameService2/Bin/Scp/Item.csv"
+	} else {
+		//	records := base.LoadCsvCfg("E://ChatGameService2/Bin/Scp/Level.csv").Records
+		path = "../Scp/Item.csv"
+	}
+	records := base.LoadCsvCfg(path).Records
+	//	records := base.LoadCsvCfg("E://ChatGameService2/Bin/Scp/Item.csv").Records
+	//file, err := os.Open(fmt.Sprintf("E://ChatGameService2/Scp/Item.csv", tag))
+	for i := 4; i < len(records); i++ {
+		item := new(ItemItem)
+		cr := reflect.ValueOf(item).Elem()
+		for k, v := range records[i].Record {
+			k = base.StrFirstToUpper(k)
+			a := cr.FieldByName(k)
+			switch a.Type().String() {
+			case "string":
+				a.Set(reflect.ValueOf(v))
+			case "int32":
+				i, _ := strconv.Atoi(v)
+				a.Set(reflect.ValueOf(int32(i)))
+			case "float64":
+				f, _ := strconv.ParseFloat(v, 64)
+				a.Set(reflect.ValueOf(f))
+			}
+		}
+		scp.dataList[item.Id] = item
+	}
+}
+
+func (scp *Item) Get(key int32) (interface{}, error) {
+	data, ok := scp.dataList[key]
+	if ok {
+		return data, nil
+	} else {
+		return nil, errors.New("not find")
+	}
+}

+ 74 - 0
Server/Scheme/SchemeLevel.go

@@ -0,0 +1,74 @@
+package scheme
+
+import (
+	"Server-Core/Server/Base"
+	"errors"
+	"reflect"
+	"strconv"
+)
+
+type LevelItem struct {
+	Level            int32
+	Exp              int32
+	HeroMaxLevel     int32
+	MaxEnergy        int32
+	MaxStorageEnergy int32
+	LevelPrize       string
+}
+
+type Level struct {
+	dataList map[int32]*LevelItem
+}
+
+func (scp *Level) Load() {
+	scp.dataList = make(map[int32]*LevelItem)
+	//records := base.LoadCsvCfg("../Scp/Level.csv").Records
+
+	//records := base.LoadCsvCfg("E://ChatGameService2/Bin/Scp/Level.csv").Records
+	var path string = ""
+	if ip == "192.168.1.122" {
+		path = "E://ChatGameService2/Bin/Scp/Level.csv"
+	} else {
+		//	records := base.LoadCsvCfg("E://ChatGameService2/Bin/Scp/Level.csv").Records
+		path = "../Scp/Level.csv"
+	}
+	records := base.LoadCsvCfg(path).Records
+	for i := 4; i < len(records); i++ {
+		item := new(LevelItem)
+		cr := reflect.ValueOf(item).Elem()
+		for k, v := range records[i].Record {
+			k = base.StrFirstToUpper(k)
+			a := cr.FieldByName(k)
+			switch a.Type().String() {
+			case "string":
+				a.Set(reflect.ValueOf(v))
+			case "int32":
+				i, _ := strconv.Atoi(v)
+				a.Set(reflect.ValueOf(int32(i)))
+			case "float64":
+				f, _ := strconv.ParseFloat(v, 64)
+				a.Set(reflect.ValueOf(f))
+			}
+		}
+		scp.dataList[item.Level] = item
+	}
+}
+
+func (scp *Level) Get(key int32) (interface{}, error) {
+	data, ok := scp.dataList[key]
+	if ok {
+		return data, nil
+	} else {
+		return nil, errors.New("not find")
+	}
+}
+
+func (scp *Level) GetMaxLevel() int32 {
+	var maxLevel int32 = 0
+	for _, item := range scp.dataList {
+		if item.Level > maxLevel {
+			maxLevel = item.Level
+		}
+	}
+	return maxLevel
+}

+ 27 - 0
Server/Scheme/SchemeMgr.go

@@ -0,0 +1,27 @@
+package scheme
+
+import log "Server-Core/Server/Base/Log"
+
+var mgr *Mgr
+
+type Mgr struct {
+	schemeList [ID_Max]Scp
+}
+
+func Create() {
+	mgr = new(Mgr)
+	Register()
+	Load()
+}
+
+func Load() {
+	for i := ID_Min + 1; i < ID_Max; i++ {
+		mgr.schemeList[i].Load()
+	}
+}
+
+func GetSchemeById(id ID) Scp {
+	log.Info("id", id)
+	log.Info("mgr", mgr)
+	return mgr.schemeList[id]
+}

+ 58 - 0
Server/Scheme/SchemeRole.go

@@ -0,0 +1,58 @@
+package scheme
+
+import (
+	"Server-Core/Server/Base"
+	"errors"
+	"reflect"
+	"strconv"
+)
+
+type RoleItem struct {
+	Id int32
+}
+
+type Role struct {
+	dataList map[int32]*RoleItem
+}
+
+func (scp *Role) Load() {
+	scp.dataList = make(map[int32]*RoleItem)
+	//records := base.LoadCsvCfg("../Scp/Role.csv").Records
+	var path string = ""
+	if ip == "192.168.1.122" {
+		path = "E://ChatGameService2/Bin/Scp/Role.csv"
+	} else {
+		//	records := base.LoadCsvCfg("E://ChatGameService2/Bin/Scp/Level.csv").Records
+		path = "../Scp/Role.csv"
+	}
+	records := base.LoadCsvCfg(path).Records
+	//records := base.LoadCsvCfg("E://ChatGameService2/Bin/Scp/Role.csv").Records
+	for i := 4; i < len(records); i++ {
+		item := new(RoleItem)
+		cr := reflect.ValueOf(item).Elem()
+		for k, v := range records[i].Record {
+			k = base.StrFirstToUpper(k)
+			a := cr.FieldByName(k)
+			switch a.Type().String() {
+			case "string":
+				a.Set(reflect.ValueOf(v))
+			case "int32":
+				i, _ := strconv.Atoi(v)
+				a.Set(reflect.ValueOf(int32(i)))
+			case "float64":
+				f, _ := strconv.ParseFloat(v, 64)
+				a.Set(reflect.ValueOf(f))
+			}
+		}
+		scp.dataList[item.Id] = item
+	}
+}
+
+func (scp *Role) Get(key int32) (interface{}, error) {
+	data, ok := scp.dataList[key]
+	if ok {
+		return data, nil
+	} else {
+		return nil, errors.New("not find")
+	}
+}

+ 62 - 0
Server/Scheme/SchemeRoleLevel.go

@@ -0,0 +1,62 @@
+package scheme
+
+import (
+	"Server-Core/Server/Base"
+	"errors"
+	"reflect"
+	"strconv"
+)
+
+type RoleLevelItem struct {
+	Level int32
+	Cost  string
+	Id    int32
+	Role  int32
+}
+
+type RoleLevel struct {
+	dataList map[int32]*RoleLevelItem
+}
+
+func (scp *RoleLevel) Load() {
+	scp.dataList = make(map[int32]*RoleLevelItem)
+	//records := base.LoadCsvCfg("../Scp/RoleLevel.csv").Records
+	//records := base.LoadCsvCfg("./Scp/RoleLevel.csv").Records
+	var path string = ""
+	if ip == "192.168.1.122" {
+		path = "E://ChatGameService2/Bin/Scp/RoleLevel.csv"
+	} else {
+		//	records := base.LoadCsvCfg("E://ChatGameService2/Bin/Scp/Level.csv").Records
+		path = "../Scp/RoleLevel.csv"
+	}
+	records := base.LoadCsvCfg(path).Records
+	//records := base.LoadCsvCfg("E://ChatGameService2/Bin/Scp/RoleLevel.csv").Records
+	for i := 4; i < len(records); i++ {
+		item := new(RoleLevelItem)
+		cr := reflect.ValueOf(item).Elem()
+		for k, v := range records[i].Record {
+			k = base.StrFirstToUpper(k)
+			a := cr.FieldByName(k)
+			switch a.Type().String() {
+			case "string":
+				a.Set(reflect.ValueOf(v))
+			case "int32":
+				i, _ := strconv.Atoi(v)
+				a.Set(reflect.ValueOf(int32(i)))
+			case "float64":
+				f, _ := strconv.ParseFloat(v, 64)
+				a.Set(reflect.ValueOf(f))
+			}
+		}
+		scp.dataList[item.Id] = item
+	}
+}
+
+func (scp *RoleLevel) Get(key int32) (interface{}, error) {
+	data, ok := scp.dataList[key]
+	if ok {
+		return data, nil
+	} else {
+		return nil, errors.New("not find")
+	}
+}

+ 117 - 0
Server/Scheme/SchemeSz.go

@@ -0,0 +1,117 @@
+package scheme
+
+import (
+	"Server-Core/Server/Base"
+	"reflect"
+	"strconv"
+)
+
+// ds,weight,playerNum,finialPlane,finialArea,finialPoint
+type SzItem struct {
+	Ds          int32 //点数
+	Weight      int32 //权重
+	PlayerNum   int32 //游戏人数(是否是4个人玩,1是,2否)
+	FinialPlane int32 //是否最后一架飞机(1是,2否)
+	FinialArea  int32 //是否到达终点区(1是,2否)
+	FinialPoint int32 //到达终点区所需要的点数
+}
+
+type Sz struct {
+	DataList []*SzItem
+}
+
+func (scp *Sz) Load() {
+	//var dataList = []*SzItem{}
+	//	scp.dataList = make(map[int32]*SzItem)
+	//records := base.LoadCsvCfg("../Scp/Level.csv").Records
+
+	//records := base.LoadCsvCfg("E://ChatGameService2/Bin/Scp/Level.csv").Records
+	var path string = ""
+	if ip == "192.168.1.122" {
+		//path = "E://ChatGameService2/Bin/Scp/Level.csv"
+		path = "E://ChatGameService2/Bin/Scp/Sz.csv"
+	} else {
+		//	records := base.LoadCsvCfg("E://ChatGameService2/Bin/Scp/Level.csv").Records
+		path = "../Scp/Sz.csv"
+	}
+	records := base.LoadCsvCfg(path).Records
+	for i := 4; i < len(records); i++ {
+		item := new(SzItem)
+		cr := reflect.ValueOf(item).Elem()
+		for k, v := range records[i].Record {
+			k = base.StrFirstToUpper(k)
+			a := cr.FieldByName(k)
+			/*	switch a.Type().String() {
+				case "string":
+					a.Set(reflect.ValueOf(v))
+				case "int32":
+					i, _ := strconv.Atoi(v)
+					a.Set(reflect.ValueOf(int32(i)))
+				case "float64":
+					f, _ := strconv.ParseFloat(v, 64)
+					a.Set(reflect.ValueOf(f))
+				}*/
+			i, _ := strconv.Atoi(v)
+			//	log.Info("i", i)
+			a.Set(reflect.ValueOf(int32(i)))
+		}
+		//scp.dataList[item.Level] = item
+		scp.DataList = append(scp.DataList, item)
+		//log.Info("item", item)
+	}
+}
+
+func (scp *Sz) Get(key int32) (interface{}, error) {
+	/*data, ok := scp.dataList[key]
+	if ok {
+		return data, nil
+	} else {
+		return nil, errors.New("not find")
+	}*/
+	return nil, nil
+}
+
+func (scp *Sz) LoadData() {
+	var dataList = []*SzItem{}
+	//var sz =Sz{};
+
+	//	scp.dataList = make(map[int32]*SzItem)
+	//records := base.LoadCsvCfg("../Scp/Level.csv").Records
+
+	//records := base.LoadCsvCfg("E://ChatGameService2/Bin/Scp/Level.csv").Records
+	var path string = ""
+	if ip == "192.168.1.122" {
+		//path = "E://ChatGameService2/Bin/Scp/Level.csv"
+		path = "E://ChatGameService2/Bin/Scp/Sz.csv"
+	} else {
+		//	records := base.LoadCsvCfg("E://ChatGameService2/Bin/Scp/Level.csv").Records
+		path = "../Scp/Sz.csv"
+	}
+	records := base.LoadCsvCfg(path).Records
+	for i := 4; i < len(records); i++ {
+		item := new(SzItem)
+		cr := reflect.ValueOf(item).Elem()
+		for k, v := range records[i].Record {
+			k = base.StrFirstToUpper(k)
+			a := cr.FieldByName(k)
+			/*	switch a.Type().String() {
+				case "string":
+					a.Set(reflect.ValueOf(v))
+				case "int32":
+					i, _ := strconv.Atoi(v)
+					a.Set(reflect.ValueOf(int32(i)))
+				case "float64":
+					f, _ := strconv.ParseFloat(v, 64)
+					a.Set(reflect.ValueOf(f))
+				}*/
+			i1, _ := strconv.Atoi(v)
+			//	log.Info("i", i)
+			a.Set(reflect.ValueOf(int32(i1)))
+		}
+		//scp.dataList[item.Level] = item
+		dataList = append(dataList, item)
+		//log.Info("item", item)
+	}
+	scp.DataList = dataList
+	//return sz
+}

+ 30 - 0
Server/Scp/Item.csv

@@ -0,0 +1,30 @@
+索引,品质,物品类型,类型参数,价值
+INT,INT,STRING,INT,INT
+32,32,256,32,32
+id,quality,type,value,price
+1,0,Item,0,2
+2,0,Item,0,100
+4,0,Item,0,1
+5,0,Item,0,1000
+6,0,Item,0,1
+101,0,Gift,302,1
+102,0,Item,0,500
+103,0,Item,0,1
+104,0,Item,0,1000
+105,0,Item,0,1000
+106,0,Item,0,1000
+107,0,Item,0,1000
+108,0,Item,0,1000
+201,0,Item,0,8000
+202,0,Item,0,30000
+301,0,Item,0,5000
+400,0,Gift,301,10000
+401,0,Item,0,10000
+402,0,Item,0,10000
+403,0,Item,0,10000
+404,0,Item,0,10000
+501,1,Gift,201,10000
+502,2,Gift,202,10000
+503,3,Gift,203,10000
+504,4,Gift,204,10000
+505,5,Gift,205,10000

+ 54 - 0
Server/Scp/Level.csv

@@ -0,0 +1,54 @@
+等级,升至下级所需经验,英雄等级上限,体力上限,体力储存上限,升至本级的奖励
+INT,INT,INT,INT,INT,STRING
+32,32,32,32,32,256
+level,exp,heroMaxLevel,maxEnergy,maxStorageEnergy,levelPrize
+1,100,4,30,300,
+2,150,8,30,300,Item_2_20
+3,200,12,30,300,Item_2_20
+4,250,16,30,300,Item_2_20
+5,300,20,30,300,Item_2_20
+6,350,24,30,300,Item_2_20
+7,400,28,30,300,Item_2_20
+8,500,32,30,300,Item_2_20
+9,600,36,30,300,Item_2_20
+10,700,40,30,300,Item_2_20
+11,800,44,30,300,Item_2_20
+12,900,48,30,300,Item_2_20
+13,1000,52,30,300,Item_2_20
+14,1100,56,30,300,Item_2_20
+15,1300,60,30,300,Item_2_20
+16,1500,64,30,300,Item_2_20
+17,1700,68,30,300,Item_2_20
+18,1900,72,30,300,Item_2_20
+19,2100,76,30,300,Item_2_20
+20,2300,80,30,300,Item_2_20
+21,2500,84,30,300,Item_2_20
+22,2900,88,30,300,Item_2_20
+23,3300,92,30,300,Item_2_20
+24,3700,96,30,300,Item_2_20
+25,4100,100,30,300,Item_2_20
+26,4500,104,30,300,Item_2_20
+27,4900,108,30,300,Item_2_20
+28,5300,112,30,300,Item_2_20
+29,6100,116,30,300,Item_2_20
+30,6900,120,30,300,Item_2_20
+31,7700,124,30,300,Item_2_20
+32,8500,128,30,300,Item_2_20
+33,9300,132,30,300,Item_2_20
+34,10100,136,30,300,Item_2_20
+35,10900,140,30,300,Item_2_20
+36,12500,144,30,300,Item_2_20
+37,14100,148,30,300,Item_2_20
+38,15700,152,30,300,Item_2_20
+39,17300,156,30,300,Item_2_20
+40,18900,160,30,300,Item_2_20
+41,20500,164,30,300,Item_2_20
+42,22100,168,30,300,Item_2_20
+43,25300,172,30,300,Item_2_20
+44,28500,176,30,300,Item_2_20
+45,31700,180,30,300,Item_2_20
+46,34900,184,30,300,Item_2_20
+47,38100,188,30,300,Item_2_20
+48,41300,192,30,300,Item_2_20
+49,44500,196,30,300,Item_2_20
+50,47700,200,30,300,Item_2_20

+ 64 - 0
Server/Scp/Role.csv

@@ -0,0 +1,64 @@
+英雄Id
+INT
+32
+id
+1
+2
+3
+4
+11
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1010
+1011
+1101
+1103
+1105
+1201
+1205
+1210
+2001
+2002
+2003
+2004
+2005
+2006
+2007
+2008
+2009
+2010
+2011
+2012
+2013
+2014
+2016
+2017
+2105
+2110
+3001
+3002
+3003
+3004
+3005
+3006
+3007
+3010
+3105
+4001
+4002
+4003
+4005
+4006
+4007
+4012
+4013
+4014
+4015
+4016
+4017

+ 404 - 0
Server/Scp/RoleLevel.csv

@@ -0,0 +1,404 @@
+序号,英雄Id,英雄等级,升级消耗
+INT,INT,INT,STRING
+32,32,32,256
+id,role,level,cost
+1,1,1,Item_1_100
+2,1,2,Item_1_120
+3,1,3,Item_1_140
+4,1,4,Item_1_160
+5,1,5,Item_1_180
+6,1,6,Item_1_200
+7,1,7,Item_1_220
+8,1,8,Item_1_240
+9,1,9,Item_1_260
+10,1,10,Item_1_280
+11,1,11,Item_1_300
+12,1,12,Item_1_320
+13,1,13,Item_1_340
+14,1,14,Item_1_380
+15,1,15,Item_1_420
+16,1,16,Item_1_460
+17,1,17,Item_1_500
+18,1,18,Item_1_540
+19,1,19,Item_1_580
+20,1,20,Item_1_620
+21,1,21,Item_1_660
+22,1,22,Item_1_700
+23,1,23,Item_1_740
+24,1,24,Item_1_780
+25,1,25,Item_1_820
+26,1,26,Item_1_860
+27,1,27,Item_1_900
+28,1,28,Item_1_980
+29,1,29,Item_1_1060
+30,1,30,Item_1_1140
+31,1,31,Item_1_1220
+32,1,32,Item_1_1300
+33,1,33,Item_1_1380
+34,1,34,Item_1_1460
+35,1,35,Item_1_1540
+36,1,36,Item_1_1620
+37,1,37,Item_1_1700
+38,1,38,Item_1_1780
+39,1,39,Item_1_1860
+40,1,40,Item_1_1940
+41,1,41,Item_1_2020
+42,1,42,Item_1_2180
+43,1,43,Item_1_2340
+44,1,44,Item_1_2500
+45,1,45,Item_1_2660
+46,1,46,Item_1_2820
+47,1,47,Item_1_2980
+48,1,48,Item_1_3140
+49,1,49,Item_1_3300
+50,1,50,Item_1_3460
+51,1,51,Item_1_3620
+52,1,52,Item_1_3780
+53,1,53,Item_1_3940
+54,1,54,Item_1_4100
+55,1,55,Item_1_4260
+56,1,56,Item_1_4420
+57,1,57,Item_1_4740
+58,1,58,Item_1_5060
+59,1,59,Item_1_5380
+60,1,60,Item_1_5700
+61,1,61,Item_1_6020
+62,1,62,Item_1_6340
+63,1,63,Item_1_6660
+64,1,64,Item_1_6980
+65,1,65,Item_1_7300
+66,1,66,Item_1_7620
+67,1,67,Item_1_7940
+68,1,68,Item_1_8260
+69,1,69,Item_1_8580
+70,1,70,Item_1_8900
+71,1,71,Item_1_9540
+72,1,72,Item_1_10180
+73,1,73,Item_1_10820
+74,1,74,Item_1_11460
+75,1,75,Item_1_12100
+76,1,76,Item_1_12740
+77,1,77,Item_1_13380
+78,1,78,Item_1_14020
+79,1,79,Item_1_14660
+80,1,80,Item_1_15300
+81,1,81,Item_1_15940
+82,1,82,Item_1_16580
+83,1,83,Item_1_17220
+84,1,84,Item_1_17860
+85,1,85,Item_1_19140
+86,1,86,Item_1_20420
+87,1,87,Item_1_21700
+88,1,88,Item_1_22980
+89,1,89,Item_1_24260
+90,1,90,Item_1_25540
+91,1,91,Item_1_26820
+92,1,92,Item_1_28100
+93,1,93,Item_1_29380
+94,1,94,Item_1_30660
+95,1,95,Item_1_31940
+96,1,96,Item_1_33220
+97,1,97,Item_1_34500
+98,1,98,Item_1_35780
+99,1,99,Item_1_37060
+100,1,100,0
+101,2,1,Item_1_100
+102,2,2,Item_1_120
+103,2,3,Item_1_140
+104,2,4,Item_1_160
+105,2,5,Item_1_180
+106,2,6,Item_1_200
+107,2,7,Item_1_220
+108,2,8,Item_1_240
+109,2,9,Item_1_260
+110,2,10,Item_1_280
+111,2,11,Item_1_300
+112,2,12,Item_1_320
+113,2,13,Item_1_340
+114,2,14,Item_1_380
+115,2,15,Item_1_420
+116,2,16,Item_1_460
+117,2,17,Item_1_500
+118,2,18,Item_1_540
+119,2,19,Item_1_580
+120,2,20,Item_1_620
+121,2,21,Item_1_660
+122,2,22,Item_1_700
+123,2,23,Item_1_740
+124,2,24,Item_1_780
+125,2,25,Item_1_820
+126,2,26,Item_1_860
+127,2,27,Item_1_900
+128,2,28,Item_1_980
+129,2,29,Item_1_1060
+130,2,30,Item_1_1140
+131,2,31,Item_1_1220
+132,2,32,Item_1_1300
+133,2,33,Item_1_1380
+134,2,34,Item_1_1460
+135,2,35,Item_1_1540
+136,2,36,Item_1_1620
+137,2,37,Item_1_1700
+138,2,38,Item_1_1780
+139,2,39,Item_1_1860
+140,2,40,Item_1_1940
+141,2,41,Item_1_2020
+142,2,42,Item_1_2180
+143,2,43,Item_1_2340
+144,2,44,Item_1_2500
+145,2,45,Item_1_2660
+146,2,46,Item_1_2820
+147,2,47,Item_1_2980
+148,2,48,Item_1_3140
+149,2,49,Item_1_3300
+150,2,50,Item_1_3460
+151,2,51,Item_1_3620
+152,2,52,Item_1_3780
+153,2,53,Item_1_3940
+154,2,54,Item_1_4100
+155,2,55,Item_1_4260
+156,2,56,Item_1_4420
+157,2,57,Item_1_4740
+158,2,58,Item_1_5060
+159,2,59,Item_1_5380
+160,2,60,Item_1_5700
+161,2,61,Item_1_6020
+162,2,62,Item_1_6340
+163,2,63,Item_1_6660
+164,2,64,Item_1_6980
+165,2,65,Item_1_7300
+166,2,66,Item_1_7620
+167,2,67,Item_1_7940
+168,2,68,Item_1_8260
+169,2,69,Item_1_8580
+170,2,70,Item_1_8900
+171,2,71,Item_1_9540
+172,2,72,Item_1_10180
+173,2,73,Item_1_10820
+174,2,74,Item_1_11460
+175,2,75,Item_1_12100
+176,2,76,Item_1_12740
+177,2,77,Item_1_13380
+178,2,78,Item_1_14020
+179,2,79,Item_1_14660
+180,2,80,Item_1_15300
+181,2,81,Item_1_15940
+182,2,82,Item_1_16580
+183,2,83,Item_1_17220
+184,2,84,Item_1_17860
+185,2,85,Item_1_19140
+186,2,86,Item_1_20420
+187,2,87,Item_1_21700
+188,2,88,Item_1_22980
+189,2,89,Item_1_24260
+190,2,90,Item_1_25540
+191,2,91,Item_1_26820
+192,2,92,Item_1_28100
+193,2,93,Item_1_29380
+194,2,94,Item_1_30660
+195,2,95,Item_1_31940
+196,2,96,Item_1_33220
+197,2,97,Item_1_34500
+198,2,98,Item_1_35780
+199,2,99,Item_1_37060
+200,2,100,0
+201,3,1,Item_1_100
+202,3,2,Item_1_120
+203,3,3,Item_1_140
+204,3,4,Item_1_160
+205,3,5,Item_1_180
+206,3,6,Item_1_200
+207,3,7,Item_1_220
+208,3,8,Item_1_240
+209,3,9,Item_1_260
+210,3,10,Item_1_280
+211,3,11,Item_1_300
+212,3,12,Item_1_320
+213,3,13,Item_1_340
+214,3,14,Item_1_380
+215,3,15,Item_1_420
+216,3,16,Item_1_460
+217,3,17,Item_1_500
+218,3,18,Item_1_540
+219,3,19,Item_1_580
+220,3,20,Item_1_620
+221,3,21,Item_1_660
+222,3,22,Item_1_700
+223,3,23,Item_1_740
+224,3,24,Item_1_780
+225,3,25,Item_1_820
+226,3,26,Item_1_860
+227,3,27,Item_1_900
+228,3,28,Item_1_980
+229,3,29,Item_1_1060
+230,3,30,Item_1_1140
+231,3,31,Item_1_1220
+232,3,32,Item_1_1300
+233,3,33,Item_1_1380
+234,3,34,Item_1_1460
+235,3,35,Item_1_1540
+236,3,36,Item_1_1620
+237,3,37,Item_1_1700
+238,3,38,Item_1_1780
+239,3,39,Item_1_1860
+240,3,40,Item_1_1940
+241,3,41,Item_1_2020
+242,3,42,Item_1_2180
+243,3,43,Item_1_2340
+244,3,44,Item_1_2500
+245,3,45,Item_1_2660
+246,3,46,Item_1_2820
+247,3,47,Item_1_2980
+248,3,48,Item_1_3140
+249,3,49,Item_1_3300
+250,3,50,Item_1_3460
+251,3,51,Item_1_3620
+252,3,52,Item_1_3780
+253,3,53,Item_1_3940
+254,3,54,Item_1_4100
+255,3,55,Item_1_4260
+256,3,56,Item_1_4420
+257,3,57,Item_1_4740
+258,3,58,Item_1_5060
+259,3,59,Item_1_5380
+260,3,60,Item_1_5700
+261,3,61,Item_1_6020
+262,3,62,Item_1_6340
+263,3,63,Item_1_6660
+264,3,64,Item_1_6980
+265,3,65,Item_1_7300
+266,3,66,Item_1_7620
+267,3,67,Item_1_7940
+268,3,68,Item_1_8260
+269,3,69,Item_1_8580
+270,3,70,Item_1_8900
+271,3,71,Item_1_9540
+272,3,72,Item_1_10180
+273,3,73,Item_1_10820
+274,3,74,Item_1_11460
+275,3,75,Item_1_12100
+276,3,76,Item_1_12740
+277,3,77,Item_1_13380
+278,3,78,Item_1_14020
+279,3,79,Item_1_14660
+280,3,80,Item_1_15300
+281,3,81,Item_1_15940
+282,3,82,Item_1_16580
+283,3,83,Item_1_17220
+284,3,84,Item_1_17860
+285,3,85,Item_1_19140
+286,3,86,Item_1_20420
+287,3,87,Item_1_21700
+288,3,88,Item_1_22980
+289,3,89,Item_1_24260
+290,3,90,Item_1_25540
+291,3,91,Item_1_26820
+292,3,92,Item_1_28100
+293,3,93,Item_1_29380
+294,3,94,Item_1_30660
+295,3,95,Item_1_31940
+296,3,96,Item_1_33220
+297,3,97,Item_1_34500
+298,3,98,Item_1_35780
+299,3,99,Item_1_37060
+300,3,100,0
+301,4,1,Item_1_100
+302,4,2,Item_1_120
+303,4,3,Item_1_140
+304,4,4,Item_1_160
+305,4,5,Item_1_180
+306,4,6,Item_1_200
+307,4,7,Item_1_220
+308,4,8,Item_1_240
+309,4,9,Item_1_260
+310,4,10,Item_1_280
+311,4,11,Item_1_300
+312,4,12,Item_1_320
+313,4,13,Item_1_340
+314,4,14,Item_1_380
+315,4,15,Item_1_420
+316,4,16,Item_1_460
+317,4,17,Item_1_500
+318,4,18,Item_1_540
+319,4,19,Item_1_580
+320,4,20,Item_1_620
+321,4,21,Item_1_660
+322,4,22,Item_1_700
+323,4,23,Item_1_740
+324,4,24,Item_1_780
+325,4,25,Item_1_820
+326,4,26,Item_1_860
+327,4,27,Item_1_900
+328,4,28,Item_1_980
+329,4,29,Item_1_1060
+330,4,30,Item_1_1140
+331,4,31,Item_1_1220
+332,4,32,Item_1_1300
+333,4,33,Item_1_1380
+334,4,34,Item_1_1460
+335,4,35,Item_1_1540
+336,4,36,Item_1_1620
+337,4,37,Item_1_1700
+338,4,38,Item_1_1780
+339,4,39,Item_1_1860
+340,4,40,Item_1_1940
+341,4,41,Item_1_2020
+342,4,42,Item_1_2180
+343,4,43,Item_1_2340
+344,4,44,Item_1_2500
+345,4,45,Item_1_2660
+346,4,46,Item_1_2820
+347,4,47,Item_1_2980
+348,4,48,Item_1_3140
+349,4,49,Item_1_3300
+350,4,50,Item_1_3460
+351,4,51,Item_1_3620
+352,4,52,Item_1_3780
+353,4,53,Item_1_3940
+354,4,54,Item_1_4100
+355,4,55,Item_1_4260
+356,4,56,Item_1_4420
+357,4,57,Item_1_4740
+358,4,58,Item_1_5060
+359,4,59,Item_1_5380
+360,4,60,Item_1_5700
+361,4,61,Item_1_6020
+362,4,62,Item_1_6340
+363,4,63,Item_1_6660
+364,4,64,Item_1_6980
+365,4,65,Item_1_7300
+366,4,66,Item_1_7620
+367,4,67,Item_1_7940
+368,4,68,Item_1_8260
+369,4,69,Item_1_8580
+370,4,70,Item_1_8900
+371,4,71,Item_1_9540
+372,4,72,Item_1_10180
+373,4,73,Item_1_10820
+374,4,74,Item_1_11460
+375,4,75,Item_1_12100
+376,4,76,Item_1_12740
+377,4,77,Item_1_13380
+378,4,78,Item_1_14020
+379,4,79,Item_1_14660
+380,4,80,Item_1_15300
+381,4,81,Item_1_15940
+382,4,82,Item_1_16580
+383,4,83,Item_1_17220
+384,4,84,Item_1_17860
+385,4,85,Item_1_19140
+386,4,86,Item_1_20420
+387,4,87,Item_1_21700
+388,4,88,Item_1_22980
+389,4,89,Item_1_24260
+390,4,90,Item_1_25540
+391,4,91,Item_1_26820
+392,4,92,Item_1_28100
+393,4,93,Item_1_29380
+394,4,94,Item_1_30660
+395,4,95,Item_1_31940
+396,4,96,Item_1_33220
+397,4,97,Item_1_34500
+398,4,98,Item_1_35780
+399,4,99,Item_1_37060
+400,4,100,0

+ 86 - 0
Server/Scp/Sz.csv

@@ -0,0 +1,86 @@
+ds,weight,playerNum,finialPlane,finialArea,finialPoint
+INT,INT,INT,INT,INT,INT
+32,32,32,32,32,32
+ds,weight,playerNum,finialPlane,finialArea,finialPoint
+1,1400,2,2,2,0
+2,2800,2,2,2,0
+3,4200,2,2,2,0
+4,5600,2,2,2,0
+5,7000,2,2,2,0
+6,10000,2,2,2,0
+1,1400,2,1,1,0
+2,2800,2,1,1,0
+3,4200,2,1,1,0
+4,5600,2,1,1,0
+5,7000,2,1,1,0
+6,10000,2,1,1,0
+1,1000,1,2,2,0
+2,2000,1,2,2,0
+3,3500,1,2,2,0
+4,5000,1,2,2,0
+5,7000,1,2,2,0
+6,10000,1,2,2,0
+1,1400,1,1,2,0
+2,2800,1,1,2,0
+3,4200,1,1,2,0
+4,5600,1,1,2,0
+5,7000,1,1,2,0
+6,10000,1,1,2,0
+1,1000,1,1,1,1
+2,2500,1,1,1,1
+3,4000,1,1,1,1
+4,5500,1,1,1,1
+5,7000,1,1,1,1
+6,10000,1,1,1,1
+1,1500,1,1,1,2
+2,2500,1,1,1,2
+3,4000,1,1,1,2
+4,5500,1,1,1,2
+5,7000,1,1,1,2
+6,10000,1,1,1,2
+1,1500,1,1,1,3
+2,3000,1,1,1,3
+3,4500,1,1,1,3
+4,5500,1,1,1,3
+5,7000,1,1,1,3
+6,10000,1,1,1,3
+1,1500,1,1,1,4
+2,3000,1,1,1,4
+3,4000,1,1,1,4
+4,5500,1,1,1,4
+5,7000,1,1,1,4
+6,10000,1,1,1,4
+1,1500,1,1,1,5
+2,3000,1,1,1,5
+3,4500,1,1,1,5
+4,6000,1,1,1,5
+5,7000,1,1,1,5
+6,10000,1,1,1,5
+1,1800,1,1,1,6
+2,3600,1,1,1,6
+3,5400,1,1,1,6
+4,7200,1,1,1,6
+5,9000,1,1,1,6
+6,10000,1,1,1,6
+,,,,,
+,,,,,
+,,,,,
+,,,,,
+,,,,,
+,,,,,
+,,,,,
+,,,,,
+,,,,,
+,,,,,
+,,,,,
+,,,,,
+,,,,,
+,,,,,
+,,,,,
+,,,,,
+,,,,,
+,,云房数据拉房失败,数据回退,,,
+,,getuserinfo函数中需要判断是否是对应的玩家,才会更新游戏人数,,,
+,,游戏结束数据回传,,,
+,,掉线重连,会掉getuserinfo接口,,,
+,,房间id初始化,,,

+ 29 - 0
Tools/Web/websockets_json.html

@@ -0,0 +1,29 @@
+<!-- websockets.html -->
+<input id="input" type="text" />
+<button onclick="send()">Send</button>
+<pre id="output"></pre>
+<script>
+    //var input = document.getElementById("input");
+    var output = document.getElementById("output");
+    var socket = new WebSocket("ws://129.204.136.65:30002/ping");
+
+	var cmd = {
+			type: 8,//命令类型
+			param: '大傻瓜'
+		}
+	var json = JSON.stringify(cmd);
+
+    socket.onopen = function () {
+        output.innerHTML += "Status: Connected\n";
+    };
+ 
+    socket.onmessage = function (e) {
+        output.innerHTML += "Server: " + e.data + "\n";
+    };
+ 
+    function send() {
+        //socket.send(input.value);
+		socket.send(json);
+        input.value = "";
+    }
+</script>

+ 24 - 0
Tools/Web/websockets_string.html

@@ -0,0 +1,24 @@
+<!-- websockets.html -->
+<input id="input" type="text" />
+<button onclick="send()">Send</button>
+<pre id="output"></pre>
+<script>
+    var input = document.getElementById("input");
+    var output = document.getElementById("output");
+    var socket = new WebSocket("ws://localhost:30002/ping");
+
+
+    socket.onopen = function () {
+        output.innerHTML += "Status: Connected\n";
+    };
+ 
+    socket.onmessage = function (e) {
+        output.innerHTML += "Server: " + e.data + "\n";
+    };
+ 
+    function send() {
+        socket.send(input.value);
+		//socket.send(json);
+        input.value = "";
+    }
+</script>

+ 4 - 0
Tools/buildPB.bat

@@ -0,0 +1,4 @@
+protoc --go_out=..\Server\Message -I ..\Proto MessageID.proto
+protoc --go_out=..\Server\Message -I ..\Proto Message.proto
+
+pause

+ 2 - 0
Tools/buildPB.sh

@@ -0,0 +1,2 @@
+protoc --go_out=../Server/Message -I ../Proto MessageID.proto
+protoc --go_out=../Server/Message -I ../Proto Message.proto

BIN
Tools/conf/conf


+ 191 - 0
Tools/conf/generator.go

@@ -0,0 +1,191 @@
+package main
+
+import (
+	"Server-Core/Server/Base"
+	"fmt"
+	"net"
+	"os"
+)
+
+func WriteS(f *os.File, s []byte) bool {
+	_, err := f.Write(s)
+	if err != nil {
+		fmt.Println(err)
+		return false
+	}
+	return true
+}
+
+func GeneratorDef() bool {
+	//file, err := os.OpenFile("../../Server/Scheme/SchemeDef.go", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666)
+	//files, _ = ioutil.ReadDir("E://ChatGameService2/Server/Scheme")
+	file, err := os.OpenFile("../../Server/Scheme/SchemeDef.go", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666)
+	if err != nil {
+		fmt.Println(err)
+		return false
+	}
+	defer file.Close()
+
+	var s = "package scheme\n\n"
+	s += "type ID int32\n"
+	s += "type G int32\n\n"
+	s += "const (\n\t"
+	s += "ID_Min = iota\n\t"
+	for _, name := range FileList {
+		s += "ID_" + name + "\n\t"
+	}
+	s += "ID_Max\n"
+	s += ")\n\n"
+	s += "const (\n"
+	//records := base.LoadCsvCfg("../../Bin/Scp/Rule.csv").Records
+	//records := base.LoadCsvCfg("./Scp/Rule.csv").Records
+	var path string = ""
+	if ip == "192.168.1.122" {
+		path = "E://ChatGameService2/Bin/Scp/Role.csv"
+	} else {
+		//	records := base.LoadCsvCfg("E://ChatGameService2/Bin/Scp/Level.csv").Records
+		path = "../Scp/Level.csv"
+	}
+	records := base.LoadCsvCfg(path).Records
+	//records := base.LoadCsvCfg("E://ChatGameService2/Bin/Scp/Rule.csv").Records
+	for i := 4; i < len(records); i++ {
+		s += "\tG_" + records[i].Record["name"] + " = " + records[i].Record["id"] + "\n"
+	}
+	s += ")\n\n"
+	s += "type Scp interface {\n\t"
+	s += "Load()\n\t"
+	s += "Get(key int32) (interface{}, error)\n"
+	s += "}\n\n"
+	s += "func Register() {\n"
+	for _, name := range FileList {
+		s += "\tmgr.schemeList[ID_" + name + "] = new(" + name + ")\n"
+	}
+	s += "}"
+
+	if !WriteS(file, []byte(s)) {
+		return false
+	}
+
+	return true
+}
+
+var ip string = ""
+
+func getIp() string {
+
+	addrList, err := net.InterfaceAddrs()
+	if err != nil {
+		panic(err)
+	}
+	for _, address := range addrList {
+		if ipNet, ok := address.(*net.IPNet); ok && !ipNet.IP.IsLoopback() {
+			if ipNet.IP.To4() != nil {
+				fmt.Println(ipNet.IP.String())
+				ip = ipNet.IP.String()
+				break
+			}
+		}
+	}
+	return ip
+}
+func GeneratorScp() bool {
+	for _, name := range FileList {
+		fileName := "Scheme" + name + ".go"
+		if SchemeMap[name] == true {
+			fmt.Println(fileName + "已经存在, 忽略")
+			continue
+		}
+
+		fmt.Println("开始生成" + fileName)
+		file, err := os.OpenFile("../../Server/Scheme/"+fileName, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666)
+		if err != nil {
+			fmt.Println(err)
+			return false
+		}
+
+		var s = "package scheme\n\n"
+		s += "import (\n\t"
+		s += "\"Server-Core/Server/Base\"\n\t"
+		s += "\"reflect\"\n\t"
+		s += "\"strconv\"\n"
+		s += ")\n\n"
+		s += "type " + name + "Item struct {\n"
+		//r := base.LoadCsvCfg("../../Bin/Scp/" + name + ".csv")
+		var path string = ""
+		if ip == "192.168.1.122" {
+			path = "E://ChatGameService2/Bin/Scp/" + name + ".csv"
+		} else {
+			//	records := base.LoadCsvCfg("E://ChatGameService2/Bin/Scp/Level.csv").Records
+			path = "./Scp/" + name + ".csv"
+		}
+
+		if ip == "192.168.1.122" {
+			path = "E://ChatGameService2/Bin/Scp/" + name + ".csv"
+		} else {
+			//	records := base.LoadCsvCfg("E://ChatGameService2/Bin/Scp/Level.csv").Records
+			path = "./Scp/" + name + ".csv"
+		}
+		r := base.LoadCsvCfg(path)
+		//	r := base.LoadCsvCfg("./Scp/" + name + ".csv")
+		//r := base.LoadCsvCfg("E://ChatGameService2/Bin/Scp/" + name + ".csv")
+		records := r.Records
+		primaryKey := ""
+		for k, v := range records[1].Record {
+			key := base.StrFirstToUpper(k)
+			if k == r.Key {
+				primaryKey = key
+			}
+			var value string
+			switch v {
+			case "INT":
+				value = "int32"
+			case "FLOAT":
+				value = "float64"
+			case "STRING":
+				value = "string"
+			default:
+				fmt.Println("类型异常: " + v)
+				return false
+			}
+			s += "\t" + key + " " + value + "\n"
+		}
+		s += "}\n\n"
+		s += "type " + name + " struct {\n\t"
+		s += "dataList map[int32]*" + name + "Item\n"
+		s += "}\n\n"
+		s += "func (scp *" + name + ") Load() {\n\t"
+		s += "scp.dataList = make(map[int32]*" + name + "Item)\n\t"
+		s += "records := base.LoadCsvCfg(\"../Scp/" + name + ".csv\").Records\n\t"
+		s += "for i := 4; i < len(records); i++ {\n\t\t"
+		s += "item := new(" + name + "Item)\n\t\t"
+		s += "cr := reflect.ValueOf(item).Elem()\n\t\t"
+		s += "for k, v := range records[i].Record {\n\t\t\t"
+		s += "k = base.StrFirstToUpper(k)\n\t\t\t"
+		s += "a := cr.FieldByName(k)\n\t\t\t"
+		s += "switch a.Type().String() {\n\t\t\t"
+		s += "case \"string\":\n\t\t\t\t"
+		s += "a.Set(reflect.ValueOf(v))\n\t\t\t"
+		s += "case \"int32\":\n\t\t\t\t"
+		s += "i, _ := strconv.Atoi(v)\n\t\t\t\t"
+		s += "a.Set(reflect.ValueOf(int32(i)))\n\t\t\t"
+		s += "case \"float64\":\n\t\t\t\t"
+		s += "f, _ := strconv.ParseFloat(v, 64)\n\t\t\t\t"
+		s += "a.Set(reflect.ValueOf(f))\n\t\t\t"
+		s += "}\n\t\t"
+		s += "}\n\t\t"
+		s += "scp.dataList[item." + primaryKey + "] = item\n\t"
+		s += "}\n"
+		s += "}\n\n"
+		s += "func (scp *" + name + ") Get(key int32) interface{} {\n\t"
+		s += "return scp.dataList[key]\n"
+		s += "}"
+
+		if !WriteS(file, []byte(s)) {
+			return false
+		}
+
+		file.Close()
+	}
+
+	return true
+}

+ 113 - 0
Tools/conf/main.go

@@ -0,0 +1,113 @@
+package main
+
+import (
+	"bufio"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"os/exec"
+	"strings"
+)
+
+var FileList []string
+var SchemeMap map[string]bool
+
+func ExecCmd(name string, arg ...string) bool {
+	cmd := exec.Command(name, arg...)
+	stdout, err := cmd.StdoutPipe()
+	if err != nil {
+		fmt.Println(err)
+		return false
+	}
+
+	stderr, err := cmd.StderrPipe()
+	if err != nil {
+		fmt.Println(err)
+		return false
+	}
+
+	err = cmd.Start()
+	if err != nil {
+		fmt.Println(err)
+		return false
+	}
+	reader := bufio.NewReader(stdout)
+	reader2 := bufio.NewReader(stderr)
+
+	for {
+		line, err := reader.ReadString('\n')
+		if err != nil {
+			if err != io.EOF {
+				fmt.Println(err)
+			}
+			break
+		}
+		fmt.Println(line)
+	}
+
+	for {
+		line, err := reader2.ReadString('\n')
+		if err != nil {
+			if err != io.EOF {
+				fmt.Println(err)
+			}
+			break
+		}
+		fmt.Println(line)
+	}
+
+	cmd.Wait()
+	return true
+}
+
+func main() {
+	/*fmt.Println("开始导出配置")
+	err := os.Chdir("../../../Tool/Bin")
+	if err != nil {
+		fmt.Println(err)
+		return
+	}
+
+	if !ExecCmd("python3", "ConfigSplit.py") {
+		return
+	}
+
+	err = os.Chdir("../../Server-Core/Tools/conf")
+	if err != nil {
+		fmt.Println(err)
+		return
+	}*/
+
+	fmt.Println("开始生成代码")
+	files, _ := ioutil.ReadDir("../../Bin/Scp")
+	for _, f := range files {
+		if f.Name() == "Attributes.csv" {
+			a := 1
+			a++
+		}
+		if strings.HasSuffix(f.Name(), "csv") {
+			FileList = append(FileList, strings.TrimSuffix(f.Name(), ".csv"))
+		}
+	}
+
+	SchemeMap = make(map[string]bool)
+	//files, _ = ioutil.ReadDir("../../Server/Scheme")
+	//E://ChatGameService2/Bin/Config/%s.conf
+	files, _ = ioutil.ReadDir("E://ChatGameService2/Server/Scheme")
+	for _, f := range files {
+		name := strings.TrimPrefix(f.Name(), "Scheme")
+		name = strings.TrimSuffix(name, ".go")
+		SchemeMap[name] = true
+	}
+
+	fmt.Println("开始生成SchemeDef.go")
+	if !GeneratorDef() {
+		return
+	}
+
+	if !GeneratorScp() {
+		return
+	}
+
+	fmt.Println("生成代码完成")
+}

+ 34 - 0
Tools/game.sql

@@ -0,0 +1,34 @@
+/*
+ Navicat Premium Data Transfer
+
+ Source Server         : docker
+ Source Server Type    : MySQL
+ Source Server Version : 80020
+ Source Host           : localhost:3307
+ Source Schema         : game
+
+ Target Server Type    : MySQL
+ Target Server Version : 80020
+ File Encoding         : 65001
+
+ Date: 01/12/2020 16:26:05
+*/
+
+SET NAMES utf8mb4;
+SET FOREIGN_KEY_CHECKS = 0;
+
+-- ----------------------------
+-- Table structure for Account
+-- isSet --客户端是否设置过数据
+-- ----------------------------
+DROP TABLE IF EXISTS `Account`;
+CREATE TABLE `Account` (
+  `playerId` bigint NOT NULL AUTO_INCREMENT,
+  `uid` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
+  `nickName` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL DEFAULT '',
+  `passWd` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
+  `createDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
+  `updateDate` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
+  `lastLoginTime` bigint NOT NULL DEFAULT '0',
+  PRIMARY KEY (`playerId`) USING BTREE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin ROW_FORMAT=DYNAMIC;

+ 36 - 0
Tools/offlineData/main.go

@@ -0,0 +1,36 @@
+/*
+@Time : 2020/9/9 15:11
+@Author : xuhanlin
+@File : Main.go
+@Description : 导出客户端离线数据
+*/
+
+package main
+
+import (
+	scheme "Server-Core/Server/Scheme"
+	"os"
+)
+
+func main() {
+	os.Chdir("/data/work/Server-Core/Bin/GameServer")
+	scheme.Create()
+	os.Chdir("/data/work/Server-Core/Tools/offlineData")
+
+	// 玩家数据
+	/*gameDataNotify := &message.GameDataNotify{TalentData: &message.TalentData{}, MiscData: &message.MiscData{}, ShopData: &message.ShopData{}}
+
+	// 基础数据
+	gameDataNotify.BaseData = &message.BaseData{}
+	gameDataNotify.BaseData.PlayerId = uint32(0)
+	gameDataNotify.BaseData.NickName = "老五请奈雪"
+	gameDataNotify.BaseData.Level = 1
+
+	//道具数据
+	levelScp := scheme.GetSchemeById(scheme.ID_Level).(*scheme.Level)
+	levelItem, _ := levelScp.Get(int32(1))
+	gameDataNotify.ItemList = append(gameDataNotify.ItemList, &message.ItemData{Id: item.CurrencyIDHP, Num: uint32(levelItem.(*scheme.LevelItem).MaxEnergy)})
+
+	rData, _ = proto.Marshal(gameDataNotify)
+	ioutil.WriteFile("gameData.bytes", rData, os.FileMode(0777))*/
+}

+ 15 - 0
build.sh

@@ -0,0 +1,15 @@
+#!/bin/sh
+
+git pull
+
+rm -f Bin/ChatGameServer/ChatGameServer
+
+docker stop chat_game_svr
+docker rm chat_game_svr
+
+docker build -t chat_game:latest .
+docker rmi -f $(docker images | grep "<none>" | awk "{print \$3}")
+docker run -d --name chat_game_svr --net=host -v /data/ChatGameService/Log:/release/Log -v /etc/timezone:/etc/timezone:ro -v /etc/localtime:/etc/localtime:ro  chat_game:latest
+
+cd Log
+tail -f info.log

+ 32 - 0
go.mod

@@ -0,0 +1,32 @@
+module Server-Core
+
+go 1.14
+
+require (
+	github.com/AgoraIO/Tools/DynamicKey/AgoraDynamicKey/go/src v0.0.0-20231113100141-1e6d53fe7ce2
+	github.com/bitly/go-simplejson v0.5.1
+	github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239 // indirect
+	github.com/gin-gonic/gin v1.9.1
+	github.com/go-redis/redis/v8 v8.0.0-beta.6
+	github.com/go-sql-driver/mysql v1.7.1
+	github.com/go-xorm/xorm v0.7.9
+	github.com/golang/protobuf v1.5.3
+	github.com/google/gopacket v1.1.19
+	github.com/gorilla/websocket v1.5.0
+	github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869 // indirect
+	github.com/jmoiron/sqlx v1.2.0
+	github.com/jonboulle/clockwork v0.2.0 // indirect
+	github.com/lestrrat-go/file-rotatelogs v2.3.0+incompatible
+	github.com/lestrrat-go/strftime v1.0.3 // indirect
+	github.com/panjf2000/gnet v1.2.0
+	github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5
+	github.com/sirupsen/logrus v1.6.0
+	github.com/tebeka/strftime v0.1.5 // indirect
+	github.com/ugorji/go v1.1.7 // indirect
+	golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
+	google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d // indirect
+	google.golang.org/grpc v1.31.1 // indirect
+	google.golang.org/protobuf v1.31.0
+	xorm.io/builder v0.3.13 // indirect
+	xorm.io/xorm v1.3.4
+)

+ 633 - 0
go.sum

@@ -0,0 +1,633 @@
+cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
+cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
+cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw=
+dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
+gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU=
+gitee.com/travelliu/dm v1.8.11192/go.mod h1:DHTzyhCrM843x9VdKVbZ+GKXGRbKM2sJ4LxihRxShkE=
+github.com/AgoraIO/Tools/DynamicKey/AgoraDynamicKey/go/src v0.0.0-20231113100141-1e6d53fe7ce2 h1:bWC/tJgOMzw/qyue9zSN3Kymi56fAGTILrwxDOuv9AE=
+github.com/AgoraIO/Tools/DynamicKey/AgoraDynamicKey/go/src v0.0.0-20231113100141-1e6d53fe7ce2/go.mod h1:4bXIK0ntDk9CqAXobmomWd7dedbfNv/aaIpmpqqzt+A=
+github.com/Azure/azure-sdk-for-go/sdk/azcore v0.19.0/go.mod h1:h6H6c8enJmmocHUbLiiGY6sx7f9i+X3m1CHdd5c6Rdw=
+github.com/Azure/azure-sdk-for-go/sdk/azidentity v0.11.0/go.mod h1:HcM1YX14R7CJcghJGOYCgdezslRSVzqwLf/q+4Y2r/0=
+github.com/Azure/azure-sdk-for-go/sdk/internal v0.7.0/go.mod h1:yqy467j36fJxcRV2TzfVZ1pCb5vxm4BtZPUdYWe/Xo8=
+github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
+github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
+github.com/DataDog/sketches-go v0.0.0-20190923095040-43f19ad77ff7 h1:qELHH0AWCvf98Yf+CNIJx9vOZOfHFDDzgDRYsnNk/vs=
+github.com/DataDog/sketches-go v0.0.0-20190923095040-43f19ad77ff7/go.mod h1:Q5DbzQ+3AkgGwymQO7aZFNP7ns2lZKGtvRBzRXfdi60=
+github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
+github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE=
+github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
+github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
+github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
+github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
+github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
+github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
+github.com/benbjohnson/clock v1.0.3 h1:vkLuvpK4fmtSCuo60+yC63p7y0BmQ8gm5ZXGuBCJyXg=
+github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM=
+github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
+github.com/bitly/go-simplejson v0.5.1 h1:xgwPbetQScXt1gh9BmoJ6j9JMr3TElvuIyjR8pgdoow=
+github.com/bitly/go-simplejson v0.5.1/go.mod h1:YOPVLzCfwK14b4Sff3oP1AmGhI9T9Vsg84etUnlyp+Q=
+github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
+github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s=
+github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U=
+github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
+github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
+github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
+github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
+github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams=
+github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
+github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY=
+github.com/chzyer/readline v1.5.0/go.mod h1:x22KAscuvRqlLoK9CsoYsmxoXZMMFVyOl86cAH8qUic=
+github.com/chzyer/test v0.0.0-20210722231415-061457976a23/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
+github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
+github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
+github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
+github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
+github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
+github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/denisenkom/go-mssqldb v0.0.0-20190707035753-2be1aa521ff4/go.mod h1:zAg7JM8CkOJ43xKXIj7eRO9kmWm/TW578qo+oDO6tuM=
+github.com/denisenkom/go-mssqldb v0.12.3/go.mod h1:k0mtMFOnU+AihqFxPMiF05rtiDrorD1Vrm1KEz5hxDo=
+github.com/dgryski/go-rendezvous v0.0.0-20200624174652-8d2f3be8b2d9 h1:h2Ul3Ym2iVZWMQGYmulVUJ4LSkBm1erp9mUkPwtMoLg=
+github.com/dgryski/go-rendezvous v0.0.0-20200624174652-8d2f3be8b2d9/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
+github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ=
+github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
+github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
+github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
+github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
+github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
+github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
+github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
+github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
+github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239 h1:Ghm4eQYC0nEPnSJdVkTrXpu9KtoVCSo1hg7mtI7G9KU=
+github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239/go.mod h1:Gdwt2ce0yfBxPvZrHkprdPPTTS3N5rwmLE8T22KBXlw=
+github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
+github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
+github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=
+github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA=
+github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
+github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
+github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14=
+github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
+github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg=
+github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU=
+github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
+github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
+github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
+github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
+github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
+github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
+github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
+github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
+github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
+github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
+github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
+github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
+github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no=
+github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
+github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
+github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
+github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1Vv0sFl1UcHBOY=
+github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI=
+github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js=
+github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
+github.com/go-redis/redis/v8 v8.0.0-beta.6 h1:QeXAkG9L5cWJA+eJTBvhkftE7dwpJ0gbMYeBE2NxXS4=
+github.com/go-redis/redis/v8 v8.0.0-beta.6/go.mod h1:g79Vpae8JMzg5qjk8BiwU9tK+HmU3iDVyS4UAJLFycI=
+github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
+github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
+github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
+github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
+github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
+github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI=
+github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
+github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
+github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:56xuuqnHyryaerycW3BfssRdxQstACi0Epw/yC5E2xM=
+github.com/go-xorm/xorm v0.7.9 h1:LZze6n1UvRmM5gpL9/U9Gucwqo6aWlFVlfcHKH10qA0=
+github.com/go-xorm/xorm v0.7.9/go.mod h1:XiVxrMMIhFkwSkh96BW7PACl7UhLtx2iJIHMdmjh5sQ=
+github.com/goccy/go-json v0.8.1 h1:4/Wjm0JIJaTDm8K1KcGrLHJoa8EsJ13YWeX+6Kfq6uI=
+github.com/goccy/go-json v0.8.1/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
+github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
+github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
+github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
+github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
+github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
+github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
+github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
+github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI=
+github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
+github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
+github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
+github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
+github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
+github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
+github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
+github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
+github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
+github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
+github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
+github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
+github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
+github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
+github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
+github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
+github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
+github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
+github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
+github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
+github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw=
+github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
+github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8=
+github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo=
+github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
+github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
+github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo=
+github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
+github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
+github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
+github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
+github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
+github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
+github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
+github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
+github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
+github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w=
+github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo=
+github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
+github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
+github.com/jackc/fake v0.0.0-20150926172116-812a484cc733/go.mod h1:WrMFNQdiFJ80sQsxDoMokWK1W5TQtxBFNpzWTD84ibQ=
+github.com/jackc/pgconn v0.0.0-20190420214824-7e0022ef6ba3/go.mod h1:jkELnwuX+w9qN5YIfX0fl88Ehu4XC3keFuOJJk9pcnA=
+github.com/jackc/pgconn v0.0.0-20190824142844-760dd75542eb/go.mod h1:lLjNuW/+OfW9/pnVKPazfWOgNfH2aPem8YQ7ilXGvJE=
+github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsUgOEh9hBm+xYTstcNHg7UPMVJqRfQxq4s=
+github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o=
+github.com/jackc/pgconn v1.9.0/go.mod h1:YctiPyvzfU11JFxoXokUOOKQXQmDMoJL9vJzHH8/2JY=
+github.com/jackc/pgconn v1.9.1-0.20210724152538-d89c8390a530/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI=
+github.com/jackc/pgconn v1.14.0/go.mod h1:9mBNlny0UvkgJdCDvdVHYSjI+8tD2rnKK69Wz8ti++E=
+github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8=
+github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE=
+github.com/jackc/pgmock v0.0.0-20201204152224-4fe30f7445fd/go.mod h1:hrBW0Enj2AZTNpt/7Y5rr2xe/9Mn757Wtb2xeBzPv2c=
+github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65/go.mod h1:5R2h2EEX+qri8jOWMbJCtaPWkrrNc7OHwsp2TCqp7ak=
+github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
+github.com/jackc/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78=
+github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA=
+github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg=
+github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM=
+github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM=
+github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
+github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
+github.com/jackc/pgproto3/v2 v2.3.2/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
+github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E=
+github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
+github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg=
+github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc=
+github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw=
+github.com/jackc/pgtype v1.8.1-0.20210724151600-32e20a603178/go.mod h1:C516IlIV9NKqfsMCXTdChteoXmwgUceqaLfjg2e3NlM=
+github.com/jackc/pgtype v1.14.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4=
+github.com/jackc/pgx v3.6.0+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I=
+github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y=
+github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM=
+github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc=
+github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs=
+github.com/jackc/pgx/v4 v4.18.0/go.mod h1:FydWkUyadDmdNH/mHnGob881GawxeEm7TcMCzkb+qQE=
+github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
+github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
+github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
+github.com/jackc/puddle v1.3.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
+github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869 h1:IPJ3dvxmJ4uczJe5YQdrYB16oTJlGSC/OyZDqUk9xX4=
+github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869/go.mod h1:cJ6Cj7dQo+O6GJNiMx+Pa94qKj+TG8ONdKHgMNIyyag=
+github.com/jmoiron/sqlx v1.2.0 h1:41Ip0zITnmWNR/vHV+S4m+VoUivnWY5E4OJfLZjCJMA=
+github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks=
+github.com/jonboulle/clockwork v0.2.0 h1:J2SLSdy7HgElq8ekSl2Mxh6vrRNFxqbXGenYH2I02Vs=
+github.com/jonboulle/clockwork v0.2.0/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8=
+github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns=
+github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
+github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
+github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
+github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
+github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
+github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
+github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
+github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
+github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk=
+github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=
+github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8=
+github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
+github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
+github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
+github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
+github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
+github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
+github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
+github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
+github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
+github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
+github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
+github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc h1:RKf14vYWi2ttpEmkA4aQ3j4u9dStX2t4M8UM6qqNsG8=
+github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc/go.mod h1:kopuH9ugFRkIXf3YoqHKyrJ9YfUFsckUU9S7B+XP+is=
+github.com/lestrrat-go/file-rotatelogs v2.3.0+incompatible h1:4mNlp+/SvALIPFpbXV3kxNJJno9iKFWGxSDE13Kl66Q=
+github.com/lestrrat-go/file-rotatelogs v2.3.0+incompatible/go.mod h1:ZQnN8lSECaebrkQytbHj4xNgtg8CR7RYXnPok8e0EHA=
+github.com/lestrrat-go/strftime v1.0.3 h1:qqOPU7y+TM8Y803I8fG9c/DyKG3xH/xkng6keC1015Q=
+github.com/lestrrat-go/strftime v1.0.3/go.mod h1:E1nN3pCbtMSu1yjSVeyuRFVm/U0xoR76fd03sz+Qz4g=
+github.com/lib/pq v1.0.0 h1:X5PMW56eZitiTeO7tKzZxFCSpbFZJtkMMooicw2us9A=
+github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
+github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
+github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
+github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
+github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
+github.com/libp2p/go-reuseport v0.0.1 h1:7PhkfH73VXfPJYKQ6JwS5I/eVcoyYi9IMNGc6FWpFLw=
+github.com/libp2p/go-reuseport v0.0.1/go.mod h1:jn6RmB1ufnQwl0Q1f+YxAj8isJgDCQzaaxIFYDhcYEA=
+github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
+github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
+github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
+github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
+github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
+github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
+github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
+github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
+github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
+github.com/mattn/go-sqlite3 v1.9.0 h1:pDRiWfl+++eC2FEFRy6jXmQlvp4Yh3z1MJKg4UeYM/4=
+github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
+github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
+github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
+github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
+github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
+github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
+github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
+github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
+github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
+github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg=
+github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
+github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
+github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
+github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8=
+github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
+github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/ginkgo v1.10.1 h1:q/mM8GF/n0shIN8SaAZ0V+jnLPzen6WIVZdiwrRlMlo=
+github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
+github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME=
+github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
+github.com/opentracing/opentracing-go v1.1.1-0.20190913142402-a7454ce5950e/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
+github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
+github.com/panjf2000/ants/v2 v2.4.0 h1:embKPQeNWMRbnrRKURv4TXJwjQRWMEAfqZT6Pe5hZNc=
+github.com/panjf2000/ants/v2 v2.4.0/go.mod h1:f6F0NZVFsGCp5A7QW/Zj/m92atWwOkY0OIhFxRNFr4A=
+github.com/panjf2000/gnet v1.2.0 h1:PoRyH1QQsnyrseSOY4TMlfs9DFqZ+qUaXtrG5HrC+CM=
+github.com/panjf2000/gnet v1.2.0/go.mod h1:Vl8hElC5vYR1iW7Txb30rFd9X12CDktkLkLgpIHKAwo=
+github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ=
+github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4=
+github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
+github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA=
+github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
+github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
+github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
+github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
+github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
+github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
+github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
+github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
+github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
+github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
+github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5 h1:mZHayPoR0lNmnHyvtYjDeq0zlVHn9K/ZXoy17ylucdo=
+github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5/go.mod h1:GEXHk5HgEKCvEIIrSpFI3ozzG5xOKA2DVlEX/gGnewM=
+github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
+github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
+github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU=
+github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc=
+github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
+github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
+github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
+github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
+github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
+github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
+github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
+github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I=
+github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
+github.com/smallnest/goframe v1.0.0/go.mod h1:Dy8560GXrB6w5OJnVBU71dJtSyINdnqHHe6atDaZX00=
+github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 h1:qLC7fQah7D6K1B0ujays3HV9gkFtllcxhzImRR7ArPQ=
+github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
+github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
+github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
+github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
+github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
+github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
+github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
+github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
+github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
+github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
+github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
+github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
+github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
+github.com/tebeka/strftime v0.1.5 h1:1NQKN1NiQgkqd/2moD6ySP/5CoZQsKa1d3ZhJ44Jpmg=
+github.com/tebeka/strftime v0.1.5/go.mod h1:29/OidkoWHdEKZqzyDLUyC+LmgDgdHo4WAFCDT7D/Ig=
+github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
+github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
+github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo=
+github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
+github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs=
+github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
+github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
+github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
+github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
+github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
+github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
+github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
+github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0=
+go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
+go.opentelemetry.io/otel v0.7.0 h1:u43jukpwqR8EsyeJOMgrsUgZwVI1e1eVw7yuzRkD1l0=
+go.opentelemetry.io/otel v0.7.0/go.mod h1:aZMyHG5TqDOXEgH2tyLiXSUKly1jT3yqE9PmrzIeCdo=
+go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
+go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
+go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
+go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
+go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
+go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
+go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
+go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
+go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
+go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
+go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
+golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
+golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k=
+golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
+golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
+golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
+golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
+golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
+golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
+golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g=
+golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
+golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
+golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
+golang.org/x/exp v0.0.0-20200513190911-00229845015e h1:rMqLP+9XLy+LdbCXHjJHAmTfXCr93W7oruWA6Hq1Alc=
+golang.org/x/exp v0.0.0-20200513190911-00229845015e/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw=
+golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
+golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
+golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
+golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
+golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
+golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
+golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
+golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
+golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
+golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
+golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
+golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA=
+golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
+golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
+golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
+golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
+golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
+golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
+golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
+golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
+golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
+golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200509044756-6aff5f38e54f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f h1:Fqb3ao1hUmOR3GkUOg/Y+BadLwykBIzs5q8Ez2SbHyc=
+golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
+golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
+golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
+golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
+golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
+golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
+golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
+golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
+golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
+golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
+golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
+golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
+golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
+golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
+google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
+google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
+google.golang.org/appengine v1.6.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
+google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
+google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
+google.golang.org/genproto v0.0.0-20191009194640-548a555dbc03/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
+google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
+google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d h1:92D1fum1bJLKSdr11OJ+54YeCMCGYIygTA7R/YZxH5M=
+google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
+google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
+google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
+google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
+google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
+google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
+google.golang.org/grpc v1.31.1 h1:SfXqXS5hkufcdZ/mHtYCh53P2b+92WQq/DZcKLgsFRs=
+google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
+google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
+google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
+google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
+google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
+google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
+google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
+google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
+google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
+google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
+google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
+google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
+google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
+google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
+google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
+google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
+google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
+gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
+gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
+gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
+gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
+gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s=
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
+gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
+gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
+lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
+lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
+modernc.org/cc/v3 v3.37.0/go.mod h1:vtL+3mdHx/wcj3iEGz84rQa8vEqR6XM84v5Lcvfph20=
+modernc.org/cc/v3 v3.38.1/go.mod h1:vtL+3mdHx/wcj3iEGz84rQa8vEqR6XM84v5Lcvfph20=
+modernc.org/cc/v3 v3.40.0/go.mod h1:/bTg4dnWkSXowUO6ssQKnOV0yMVxDYNIsIrzqTFDGH0=
+modernc.org/ccgo/v3 v3.0.0-20220904174949-82d86e1b6d56/go.mod h1:YSXjPL62P2AMSxBphRHPn7IkzhVHqkvOnRKAKh+W6ZI=
+modernc.org/ccgo/v3 v3.0.0-20220910160915-348f15de615a/go.mod h1:8p47QxPkdugex9J4n9P2tLZ9bK01yngIVp00g4nomW0=
+modernc.org/ccgo/v3 v3.16.13-0.20221017192402-261537637ce8/go.mod h1:fUB3Vn0nVPReA+7IG7yZDfjv1TMWjhQP8gCxrFAtL5g=
+modernc.org/ccgo/v3 v3.16.13/go.mod h1:2Quk+5YgpImhPjv2Qsob1DnZ/4som1lJTodubIcoUkY=
+modernc.org/ccorpus v1.11.6/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ=
+modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM=
+modernc.org/libc v1.17.4/go.mod h1:WNg2ZH56rDEwdropAJeZPQkXmDwh+JCA1s/htl6r2fA=
+modernc.org/libc v1.18.0/go.mod h1:vj6zehR5bfc98ipowQOM2nIDUZnVew/wNC/2tOGS+q0=
+modernc.org/libc v1.19.0/go.mod h1:ZRfIaEkgrYgZDl6pa4W39HgN5G/yDW+NRmNKZBDFrk0=
+modernc.org/libc v1.20.3/go.mod h1:ZRfIaEkgrYgZDl6pa4W39HgN5G/yDW+NRmNKZBDFrk0=
+modernc.org/libc v1.21.4/go.mod h1:przBsL5RDOZajTVslkugzLBj1evTue36jEomFQOoYuI=
+modernc.org/libc v1.22.2/go.mod h1:uvQavJ1pZ0hIoC/jfqNoMLURIMhKzINIWypNM17puug=
+modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
+modernc.org/memory v1.3.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=
+modernc.org/memory v1.4.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=
+modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
+modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
+modernc.org/sqlite v1.20.4/go.mod h1:zKcGyrICaxNTMEHSr1HQ2GUraP0j+845GYw37+EyT6A=
+modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw=
+modernc.org/tcl v1.15.0/go.mod h1:xRoGotBZ6dU+Zo2tca+2EqVEeMmOUBzHnhIwq4YrVnE=
+modernc.org/token v1.0.1/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
+modernc.org/z v1.7.0/go.mod h1:hVdgNMh8ggTuRG1rGU8x+xGRFfiQUIAw0ZqlPy8+HyQ=
+rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
+xorm.io/builder v0.3.6/go.mod h1:LEFAPISnRzG+zxaxj2vPicRwz67BdhFreKg8yv8/TgU=
+xorm.io/builder v0.3.11-0.20220531020008-1bd24a7dc978 h1:bvLlAPW1ZMTWA32LuZMBEGHAUOcATZjzHcotf3SWweM=
+xorm.io/builder v0.3.11-0.20220531020008-1bd24a7dc978/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE=
+xorm.io/builder v0.3.13 h1:a3jmiVVL19psGeXx8GIurTp7p0IIgqeDmwhcR6BAOAo=
+xorm.io/builder v0.3.13/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE=
+xorm.io/core v0.7.2-0.20190928055935-90aeac8d08eb h1:msX3zG3BPl8Ti+LDzP33/9K7BzO/WqFXk610K1kYKfo=
+xorm.io/core v0.7.2-0.20190928055935-90aeac8d08eb/go.mod h1:jJfd0UAEzZ4t87nbQYtVjmqpIODugN6PD2D9E+dJvdM=
+xorm.io/xorm v1.3.4 h1:vWFKzR3DhGUDl5b4srhUjhDwjxkZAc4C7BFszpu0swI=
+xorm.io/xorm v1.3.4/go.mod h1:qFJGFoVYbbIdnz2vaL5OxSQ2raleMpyRRalnq3n9OJo=

+ 12 - 0
readme.md

@@ -0,0 +1,12 @@
+
+set CGO_ENABLED=0
+set GOOS=linux
+    set GOARCH=amd6
+go build -o main-linux main.go
+
+ chmod 777 main-linux
+> ./main-linux
+
+
+docker run --restart=always --name mysql -ivileged=true -d -p 3306:3306 -v /home/lijiali/conf/my.cnf:/etc/mysql/my.cnf -v /home/lijiali/logs:/logs -v /home/lijiali/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=psGCMSfy9Vds mysql:8.0.34
+

Einige Dateien werden nicht angezeigt, da zu viele Dateien in diesem Diff geändert wurden.