forked from PySymGym/PySymGym
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmessages.py
More file actions
107 lines (79 loc) · 2.72 KB
/
messages.py
File metadata and controls
107 lines (79 loc) · 2.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import json
import logging
from dataclasses import dataclass, field
from enum import Enum
from typing import Optional
from common.game import GameMap, GameState, Reward
from config import FeatureConfig
from connection.game_server_conn.unsafe_json import obj_from_dict
from dataclasses_json import config, dataclass_json
class ClientMessageType(str, Enum):
START = "start"
STEP = "step"
STOP = "stop"
@dataclass_json
@dataclass(slots=True)
class ClientMessageBody:
def type(self) -> ClientMessageType:
pass
@dataclass_json
@dataclass(slots=True)
class StartMessageBody(ClientMessageBody, GameMap):
def type(self) -> ClientMessageType:
return ClientMessageType.START
@dataclass_json
@dataclass(slots=True)
class StepMessageBody(ClientMessageBody):
StateId: int
PredictedStateUsefulness: float
def type(self) -> ClientMessageType:
return ClientMessageType.STEP
@dataclass_json
@dataclass(slots=True)
class ClientMessage:
MessageType: str = field(init=False)
MessageBody: ClientMessageBody = field(
metadata=config(
encoder=lambda x: (
x.to_json() if issubclass(type(x), ClientMessageBody) else json.dumps(x)
)
)
)
def __post_init__(self):
self.MessageType = self.MessageBody.type()
class ServerMessageType(str, Enum):
GAMEOVER = "GameOver"
MOVE_REVARD = "MoveReward"
INCORRECT_PREDICTED_STATEID = "IncorrectPredictedStateId"
READY_FOR_NEXT_STEP = "ReadyForNextStep"
SERVER_ERROR = "ServerError"
@dataclass_json
@dataclass(slots=True)
class ServerMessage:
MessageType: ServerMessageType
class DeserializationException(Exception):
pass
def from_json_handle(data, expected) -> ClientMessage:
if FeatureConfig.DISABLE_MESSAGE_CHECKS:
return obj_from_dict(json.loads(data))
try:
return expected.from_json(data)
except Exception as e:
err_to_display = f"{type(e)} - {e}: tried to decode {expected}, got unmatched structure, registered to app.log under [ERROR] tag"
error = f"{type(e)} - {e}: tried to decode {expected}, got raw data: {json.dumps(json.loads(data), indent=2)}"
logging.error(error)
raise ServerMessage.DeserializationException(err_to_display) from e
@dataclass(slots=True)
class GameStateServerMessage(ServerMessage):
MessageBody: GameState
@dataclass(slots=True)
class RewardServerMessage(ServerMessage):
MessageBody: Reward
@dataclass(slots=True)
class GameOverServerMessageBody:
ActualCoverage: Optional[int]
TestsCount: int
ErrorsCount: int
@dataclass(slots=True)
class GameOverServerMessage(ServerMessage):
MessageBody: GameOverServerMessageBody