You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

Communication.py 11 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. import PyAPI.structures as THUAI6
  2. from PyAPI.AI import Setting
  3. from PyAPI.utils import THUAI62Proto
  4. from PyAPI.Interface import IErrorHandler
  5. import proto.Services_pb2_grpc as Services
  6. import proto.Message2Clients_pb2 as Message2Clients
  7. import threading
  8. import grpc
  9. from typing import Union
  10. # 使用gRPC的异步来减少通信对于选手而言损失的时间,而gRPC的return值有result()方法,故若连接错误时也应当返回一个具有result()方法的对象,使用此处的ErrorHandler类来实现
  11. class BoolErrorHandler(IErrorHandler):
  12. @staticmethod
  13. def result():
  14. return False
  15. class Communication:
  16. def __init__(self, sIP: str, sPort: str):
  17. aim = sIP + ":" + sPort
  18. channel = grpc.insecure_channel(aim)
  19. self.__THUAI6Stub = Services.AvailableServiceStub(channel)
  20. self.__haveNewMessage = False
  21. self.__cvMessage = threading.Condition()
  22. self.__message2Client: Message2Clients.MessageToClient
  23. self.__mtxLimit = threading.Lock()
  24. self.__counter = 0
  25. self.__counterMove = 0
  26. self.__limit = 50
  27. self.__moveLimit = 10
  28. def Move(self, time: int, angle: float, playerID: int) -> bool:
  29. try:
  30. with self.__mtxLimit:
  31. if (
  32. self.__counter >= self.__limit
  33. or self.__counterMove >= self.__moveLimit
  34. ):
  35. return False
  36. self.__counter += 1
  37. self.__counterMove += 1
  38. moveResult = self.__THUAI6Stub.Move(
  39. THUAI62Proto.THUAI62ProtobufMove(time, angle, playerID)
  40. )
  41. except grpc.RpcError as e:
  42. return False
  43. else:
  44. return moveResult.act_success
  45. def PickProp(self, propType: THUAI6.PropType, playerID: int) -> bool:
  46. try:
  47. with self.__mtxLimit:
  48. if self.__counter >= self.__limit:
  49. return False
  50. self.__counter += 1
  51. pickResult = self.__THUAI6Stub.PickProp(
  52. THUAI62Proto.THUAI62ProtobufProp(propType, playerID)
  53. )
  54. except grpc.RpcError as e:
  55. return False
  56. else:
  57. return pickResult.act_success
  58. def UseProp(self, propType: THUAI6.PropType, playerID: int) -> bool:
  59. try:
  60. with self.__mtxLimit:
  61. if self.__counter >= self.__limit:
  62. return False
  63. self.__counter += 1
  64. useResult = self.__THUAI6Stub.UseProp(
  65. THUAI62Proto.THUAI62ProtobufProp(propType, playerID)
  66. )
  67. except grpc.RpcError as e:
  68. return False
  69. else:
  70. return useResult.act_success
  71. def ThrowProp(self, propType: THUAI6.PropType, playerID: int) -> bool:
  72. try:
  73. with self.__mtxLimit:
  74. if self.__counter >= self.__limit:
  75. return False
  76. self.__counter += 1
  77. throwResult = self.__THUAI6Stub.ThrowProp(
  78. THUAI62Proto.THUAI62ProtobufProp(propType, playerID)
  79. )
  80. except grpc.RpcError as e:
  81. return False
  82. else:
  83. return throwResult.act_success
  84. def UseSkill(self, skillID: int, skillParam: int, playerID: int) -> bool:
  85. try:
  86. with self.__mtxLimit:
  87. if self.__counter >= self.__limit:
  88. return False
  89. self.__counter += 1
  90. useResult = self.__THUAI6Stub.UseSkill(
  91. THUAI62Proto.THUAI62ProtobufSkill(skillID, skillParam, playerID)
  92. )
  93. except grpc.RpcError as e:
  94. return False
  95. else:
  96. return useResult.act_success
  97. def SendMessage(self, toID: int, message: Union[str, bytes], playerID: int) -> bool:
  98. try:
  99. with self.__mtxLimit:
  100. if self.__counter >= self.__limit:
  101. return False
  102. self.__counter += 1
  103. sendResult = self.__THUAI6Stub.SendMessage(
  104. THUAI62Proto.THUAI62ProtobufSend(message, toID, playerID)
  105. )
  106. except grpc.RpcError as e:
  107. return False
  108. else:
  109. return sendResult.act_success
  110. def Graduate(self, playerID: int) -> bool:
  111. try:
  112. with self.__mtxLimit:
  113. if self.__counter >= self.__limit:
  114. return False
  115. self.__counter += 1
  116. escapeResult = self.__THUAI6Stub.Graduate(
  117. THUAI62Proto.THUAI62ProtobufID(playerID)
  118. )
  119. except grpc.RpcError as e:
  120. return False
  121. else:
  122. return escapeResult.act_success
  123. def StartLearning(self, playerID: int) -> bool:
  124. try:
  125. with self.__mtxLimit:
  126. if self.__counter >= self.__limit:
  127. return False
  128. self.__counter += 1
  129. learnResult = self.__THUAI6Stub.StartLearning(
  130. THUAI62Proto.THUAI62ProtobufID(playerID)
  131. )
  132. except grpc.RpcError as e:
  133. return False
  134. else:
  135. return learnResult.act_success
  136. def StartEncourageMate(self, playerID: int, mateID: int) -> bool:
  137. try:
  138. with self.__mtxLimit:
  139. if self.__counter >= self.__limit:
  140. return False
  141. self.__counter += 1
  142. helpResult = self.__THUAI6Stub.StartTreatMate(
  143. THUAI62Proto.THUAI62ProtobufTreatAndRescue(playerID, mateID)
  144. )
  145. except grpc.RpcError as e:
  146. return False
  147. else:
  148. return helpResult.act_success
  149. def StartRouseMate(self, playerID: int, mateID: int) -> bool:
  150. try:
  151. with self.__mtxLimit:
  152. if self.__counter >= self.__limit:
  153. return False
  154. self.__counter += 1
  155. helpResult = self.__THUAI6Stub.StartRescueMate(
  156. THUAI62Proto.THUAI62ProtobufTreatAndRescue(playerID, mateID)
  157. )
  158. except grpc.RpcError as e:
  159. return False
  160. else:
  161. return helpResult.act_success
  162. def Attack(self, angle: float, playerID: int) -> bool:
  163. try:
  164. with self.__mtxLimit:
  165. if self.__counter >= self.__limit:
  166. return False
  167. self.__counter += 1
  168. attackResult = self.__THUAI6Stub.Attack(
  169. THUAI62Proto.THUAI62ProtobufAttack(angle, playerID)
  170. )
  171. except grpc.RpcError as e:
  172. return False
  173. else:
  174. return attackResult.act_success
  175. def OpenDoor(self, playerID: int) -> bool:
  176. try:
  177. with self.__mtxLimit:
  178. if self.__counter >= self.__limit:
  179. return False
  180. self.__counter += 1
  181. openResult = self.__THUAI6Stub.OpenDoor(
  182. THUAI62Proto.THUAI62ProtobufID(playerID)
  183. )
  184. except grpc.RpcError as e:
  185. return False
  186. else:
  187. return openResult.act_success
  188. def CloseDoor(self, playerID: int) -> bool:
  189. try:
  190. with self.__mtxLimit:
  191. if self.__counter >= self.__limit:
  192. return False
  193. self.__counter += 1
  194. closeResult = self.__THUAI6Stub.CloseDoor(
  195. THUAI62Proto.THUAI62ProtobufID(playerID)
  196. )
  197. except grpc.RpcError as e:
  198. return False
  199. else:
  200. return closeResult.act_success
  201. def SkipWindow(self, playerID: int) -> bool:
  202. try:
  203. with self.__mtxLimit:
  204. if self.__counter >= self.__limit:
  205. return False
  206. self.__counter += 1
  207. skipResult = self.__THUAI6Stub.SkipWindow(
  208. THUAI62Proto.THUAI62ProtobufID(playerID)
  209. )
  210. except grpc.RpcError as e:
  211. return False
  212. else:
  213. return skipResult.act_success
  214. def StartOpenGate(self, playerID: int) -> bool:
  215. try:
  216. with self.__mtxLimit:
  217. if self.__counter >= self.__limit:
  218. return False
  219. self.__counter += 1
  220. openResult = self.__THUAI6Stub.StartOpenGate(
  221. THUAI62Proto.THUAI62ProtobufID(playerID)
  222. )
  223. except grpc.RpcError as e:
  224. return False
  225. else:
  226. return openResult.act_success
  227. def StartOpenChest(self, playerID: int) -> bool:
  228. try:
  229. with self.__mtxLimit:
  230. if self.__counter >= self.__limit:
  231. return False
  232. self.__counter += 1
  233. openResult = self.__THUAI6Stub.StartOpenChest(
  234. THUAI62Proto.THUAI62ProtobufID(playerID)
  235. )
  236. except grpc.RpcError as e:
  237. return False
  238. else:
  239. return openResult.act_success
  240. def EndAllAction(self, playerID: int) -> bool:
  241. try:
  242. with self.__mtxLimit:
  243. if (
  244. self.__counter >= self.__limit
  245. or self.__counterMove >= self.__moveLimit
  246. ):
  247. return False
  248. self.__counter += 1
  249. self.__counterMove += 1
  250. endResult = self.__THUAI6Stub.EndAllAction(
  251. THUAI62Proto.THUAI62ProtobufID(playerID)
  252. )
  253. except grpc.RpcError as e:
  254. return False
  255. else:
  256. return endResult.act_success
  257. def TryConnection(self, playerID: int) -> bool:
  258. try:
  259. connectResult = self.__THUAI6Stub.TryConnection(
  260. THUAI62Proto.THUAI62ProtobufID(playerID)
  261. )
  262. except grpc.RpcError as e:
  263. return False
  264. else:
  265. return True
  266. def GetMessage2Client(self) -> Message2Clients.MessageToClient:
  267. with self.__cvMessage:
  268. self.__cvMessage.wait_for(lambda: self.__haveNewMessage)
  269. self.__haveNewMessage = False
  270. return self.__message2Client
  271. def AddPlayer(self, playerID: int, playerType: THUAI6.PlayerType) -> None:
  272. def tMessage():
  273. try:
  274. if playerType == THUAI6.PlayerType.StudentPlayer:
  275. studentType = Setting.studentType()[playerID]
  276. else:
  277. studentType = THUAI6.StudentType.NullStudentType
  278. playerMsg = THUAI62Proto.THUAI62ProtobufPlayer(
  279. playerID, playerType, studentType, Setting.trickerType()
  280. )
  281. for msg in self.__THUAI6Stub.AddPlayer(playerMsg):
  282. with self.__cvMessage:
  283. self.__haveNewMessage = True
  284. self.__message2Client = msg
  285. self.__cvMessage.notify()
  286. with self.__mtxLimit:
  287. self.__counter = 0
  288. self.__counterMove = 0
  289. except grpc.RpcError as e:
  290. return
  291. threading.Thread(target=tMessage).start()