forked from mycard/srvpro
-
Notifications
You must be signed in to change notification settings - Fork 3
/
ygopro.coffee
167 lines (150 loc) · 4.54 KB
/
ygopro.coffee
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
_ = require 'underscore'
_.str = require 'underscore.string'
_.mixin(_.str.exports())
Struct = require('./struct.js').Struct
i18ns = require './i18n.json'
#常量/类型声明
structs_declaration = require './structs.json' #结构体声明
typedefs = require './typedefs.json' #类型声明
@proto_structs = require './proto_structs.json' #消息与结构体的对应,未完成,对着duelclient.cpp加
@constants = require './constants.json' #network.h里定义的常量
#结构体定义
@structs = {}
for name, declaration of structs_declaration
result = Struct()
for field in declaration
if field.encoding
switch field.encoding
when "UTF-16LE" then result.chars field.name, field.length*2, field.encoding
else throw "unsupported encoding: #{field.encoding}"
else
type = field.type
type = typedefs[type] if typedefs[type]
if field.length
result.array field.name, field.length, type #不支持结构体
else
if @structs[type]
result.struct field.name, @structs[type]
else
result[type] field.name
@structs[name] = result
#消息跟踪函数 需要重构, 另暂时只支持异步, 同步没做.
@stoc_follows = {}
@ctos_follows = {}
@stoc_follow = (proto, synchronous, callback)->
if typeof proto == 'string'
for key, value of @constants.STOC
if value == proto
proto = key
break
throw "unknown proto" if !@constants.STOC[proto]
@stoc_follows[proto] = {callback: callback, synchronous: synchronous}
return
@ctos_follow = (proto, synchronous, callback)->
if typeof proto == 'string'
for key, value of @constants.CTOS
if value == proto
proto = key
break
throw "unknown proto" if !@constants.CTOS[proto]
@ctos_follows[proto] = {callback: callback, synchronous: synchronous}
return
#消息发送函数,至少要把俩合起来....
@stoc_send = (socket, proto, info)->
#console.log proto, proto_structs.STOC[proto], structs[proto_structs.STOC[proto]]
if typeof info == 'undefined'
buffer = ""
else if Buffer.isBuffer(info)
buffer = info
else
struct = @structs[@proto_structs.STOC[proto]]
struct.allocate()
struct.set info
buffer = struct.buffer()
if typeof proto == 'string' #需要重构
for key, value of @constants.STOC
if value == proto
proto = key
break
throw "unknown proto" if !@constants.STOC[proto]
header = new Buffer(3)
header.writeUInt16LE buffer.length + 1, 0
header.writeUInt8 proto, 2
socket.write header
socket.write buffer if buffer.length
return
@ctos_send = (socket, proto, info)->
#console.log proto, proto_structs.CTOS[proto], structs[proto_structs.CTOS[proto]]
if typeof info == 'undefined'
buffer = ""
else if Buffer.isBuffer(info)
buffer = info
else
struct = @structs[@proto_structs.CTOS[proto]]
struct.allocate()
struct.set info
buffer = struct.buffer()
if typeof proto == 'string' #需要重构
for key, value of @constants.CTOS
if value == proto
proto = key
break
throw "unknown proto" if !@constants.CTOS[proto]
header = new Buffer(3)
header.writeUInt16LE buffer.length + 1, 0
header.writeUInt8 proto, 2
socket.write header
socket.write buffer if buffer.length
return
#util
@stoc_send_chat = (client, msg, player = 8)->
if !client
console.log "err stoc_send_chat"
return
for line in _.lines(msg)
if player>=10
line="[Server]: "+line
for o,r of i18ns[client.lang]
re=new RegExp("\\$\\{"+o+"\\}",'g')
line=line.replace(re,r)
@stoc_send client, 'CHAT', {
player: player
msg: line
}
return
@stoc_send_chat_to_room = (room, msg, player = 8)->
if !room
console.log "err stoc_send_chat_to_room"
return
for client in room.players
@stoc_send_chat(client, msg, player) if client
for client in room.watchers
@stoc_send_chat(client, msg, player) if client
return
@stoc_send_hint_card_to_room = (room, card)->
if !room
console.log "err stoc_send_hint_card_to_room"
return
for client in room.players
@stoc_send client, 'GAME_MSG', {
curmsg: 2,
type: 10,
player: 0,
data: card
} if client
for client in room.watchers
@stoc_send client, 'GAME_MSG', {
curmsg: 2,
type: 10,
player: 0,
data: card
} if client
return
@stoc_die = (client, msg)->
@stoc_send_chat(client, msg, @constants.COLORS.RED)
@stoc_send client, 'ERROR_MSG', {
msg: 1
code: 9
} if client
client.destroy() if client
return