Commit 85a01308 authored by 神楽坂玲奈's avatar 神楽坂玲奈

class Room

parent 06e55585
{
"name": "ygopro-server",
"version": "2.0.0",
"description": "a server for ygopro",
"repository": {
"type": "git",
"url": "https://github.com/mycard/ygopro-server.git"
},
"keywords": [
"mycard",
"ygopro",
"server"
],
"author": "zh99998 <zh99998@gmail.com>",
"dependencies": {
"underscore": "*",
"freeport": "*",
"struct": "*",
"inotify": "*"
},
"license": "GPLv3",
"main": "ygopro-server.js",
"scripts": {
"start": "forever start mycard-server-match.js",
"build": "coffee -c mycard-server-match.coffee"
},
"engines": {
"node": "*"
}
}
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
net = require 'net' #官方库
http = require 'http' net = require 'net'
url = require 'url' http = require 'http'
spawn = require('child_process').spawn url = require 'url'
path = require 'path'
fs = require 'fs'
freeport = require 'freeport' spawn = require('child_process').spawn
Struct = require('struct').Struct
_ = require 'underscore' #三方库
freeport = require 'freeport'
Struct = require('struct').Struct
_ = require 'underscore'
Inotify = require('inotify').Inotify
structs_declaration = require './structs.json' #结构体声明
typedefs = require './typedefs.json' #类型声明 #常量/类型声明
proto_structs = require './proto_structs.json' #消息与结构体的对应,未完成,对着duelclient.cpp加 structs_declaration = require './structs.json' #结构体声明
constants = require './constants.json' #network.h里定义的常量 typedefs = require './typedefs.json' #类型声明
proto_structs = require './proto_structs.json' #消息与结构体的对应,未完成,对着duelclient.cpp加
settings = require './config.json' #本机IP端口设置 constants = require './constants.json' #network.h里定义的常量
if process.argv[2] == '--debug' #配置文件
settings.port++ settings = require './config.json' #本机IP端口设置
settings.http_port++
class Room
#结构体定义 @all = []
structs = {}
for name, declaration of structs_declaration #name
result = Struct() #port
for field in declaration #players: [{client, server, name, pos}]
if field.encoding #process
switch field.encoding #established
when "UTF-16LE" then result.chars field.name, field.length*2, field.encoding #alive
else throw "unsupported encoding: #{file.encoding}" constructor: (name, port, client) ->
else @name = name
type = field.type @port = port
type = typedefs[type] if typedefs[type] @alive = true
if field.length @players = []
result.array field.name, field.length, type #不支持结构体 @add_client(client)
else Room.all.push this #这个故事告诉我们没事不要乱new Room
if structs[type]
result.struct field.name, structs[type] delete: (room)->
else delete Room.all[_.indexOf(Room.all, room)]
result[type] field.name
structs[name] = result add_client: (client)->
@players.push {client: client, name: client.player}
stoc_follows = {}
ctos_follows = {}
stoc_follow = (proto, synchronous, callback)-> #需要性能优化,建立个索引
if typeof proto == 'string' @find_by_name: (name)->
for key, value of constants.STOC _.find @all, (room)->
if value == proto room.name == name
proto = key @find_by_port: (port)->
break _.find @all, (room)->
throw "unknown proto" if !constants.STOC[proto] room.name == port
stoc_follows[proto] = {callback: callback, synchronous: synchronous} @find_by_client: (client)->
ctos_follow = (proto, synchronous, callback)-> _.find @all, (room)->
if typeof proto == 'string' _.some room.players, (player)->
for key, value of constants.CTOS player.client == client
if value == proto
proto = key
break
throw "unknown proto" if !constants.CTOS[proto]
ctos_follows[proto] = {callback: callback, synchronous: synchronous} #debug模式 端口号+1
debug = false
stoc_send = (socket, proto, info)-> if process.argv[2] == '--debug'
#console.log proto, proto_structs.STOC[proto], structs[proto_structs.STOC[proto]] settings.port++
settings.http_port++
if typeof info == 'undefined' debug = true
buffer = ""
else if Buffer.isBuffer(info) #结构体定义
buffer = info structs = {}
else for name, declaration of structs_declaration
struct = structs[proto_structs.STOC[proto]] result = Struct()
struct.allocate() for field in declaration
struct.set info if field.encoding
buffer = struct.buffer() switch field.encoding
when "UTF-16LE" then result.chars field.name, field.length*2, field.encoding
if typeof proto == 'string' #需要重构 else throw "unsupported encoding: #{file.encoding}"
for key, value of constants.STOC else
if value == proto type = field.type
proto = key type = typedefs[type] if typedefs[type]
break if field.length
throw "unknown proto" if !constants.STOC[proto] result.array field.name, field.length, type #不支持结构体
else
header = new Buffer(3) if structs[type]
header.writeUInt16LE buffer.length + 1, 0 result.struct field.name, structs[type]
header.writeUInt8 proto, 2 else
socket.write header result[type] field.name
socket.write buffer if buffer.length structs[name] = result
console.log 'stoc_sent:', buffer
ctos_send = (socket, proto, info)-> #消息跟踪函数 需要重构, 另暂时只支持异步, 同步没做.
#console.log proto, proto_structs.CTOS[proto], structs[proto_structs.CTOS[proto]] stoc_follows = {}
ctos_follows = {}
if typeof info == 'undefined' stoc_follow = (proto, synchronous, callback)->
buffer = "" if typeof proto == 'string'
else if Buffer.isBuffer(info) for key, value of constants.STOC
buffer = info if value == proto
else proto = key
struct = structs[proto_structs.CTOS[proto]] break
struct.allocate() throw "unknown proto" if !constants.STOC[proto]
struct.set info stoc_follows[proto] = {callback: callback, synchronous: synchronous}
buffer = struct.buffer() ctos_follow = (proto, synchronous, callback)->
if typeof proto == 'string'
if typeof proto == 'string' #需要重构 for key, value of constants.CTOS
for key, value of constants.CTOS if value == proto
if value == proto proto = key
proto = key break
break throw "unknown proto" if !constants.CTOS[proto]
throw "unknown proto" if !constants.CTOS[proto] ctos_follows[proto] = {callback: callback, synchronous: synchronous}
header = new Buffer(3)
header.writeUInt16LE buffer.length + 1, 0 #消息发送函数,至少要把俩合起来....
header.writeUInt8 proto, 2 stoc_send = (socket, proto, info)->
socket.write header #console.log proto, proto_structs.STOC[proto], structs[proto_structs.STOC[proto]]
socket.write buffer if buffer.length
console.log 'ctos_sent:', buffer if typeof info == 'undefined'
buffer = ""
server_listener = (port, client, server)-> else if Buffer.isBuffer(info)
client.connected = true buffer = info
console.log "connected #{port}" else
struct = structs[proto_structs.STOC[proto]]
stoc_buffer = new Buffer(0) struct.allocate()
stoc_message_length = 0 struct.set info
stoc_proto = 0 buffer = struct.buffer()
for buffer in client.pre_connecion_buffers if typeof proto == 'string' #需要重构
server.write buffer for key, value of constants.STOC
if value == proto
server.on "data", (data) -> proto = key
console.log 'server: ', data break
stoc_buffer = Buffer.concat([stoc_buffer, data], stoc_buffer.length + data.length) throw "unknown proto" if !constants.STOC[proto]
#buffer的错误使用方式,好孩子不要学
header = new Buffer(3)
while true header.writeUInt16LE buffer.length + 1, 0
if stoc_message_length == 0 header.writeUInt8 proto, 2
if stoc_buffer.length >= 2 socket.write header
stoc_message_length = stoc_buffer.readUInt16LE(0) socket.write buffer if buffer.length
else console.log 'stoc_sent:', buffer if debug
break
else if stoc_proto == 0 ctos_send = (socket, proto, info)->
if stoc_buffer.length >= 3 #console.log proto, proto_structs.CTOS[proto], structs[proto_structs.CTOS[proto]]
stoc_proto = stoc_buffer.readUInt8(2)
else if typeof info == 'undefined'
break buffer = ""
else else if Buffer.isBuffer(info)
if stoc_buffer.length >= 2 + stoc_message_length buffer = info
console.log constants.STOC[stoc_proto] else
if stoc_follows[stoc_proto] struct = structs[proto_structs.CTOS[proto]]
b = stoc_buffer.slice(3, stoc_message_length - 1 + 3) struct.allocate()
if struct = structs[proto_structs.STOC[constants.STOC[stoc_proto]]] struct.set info
struct._setBuff(b) buffer = struct.buffer()
setTimeout stoc_follows[stoc_proto].callback, 0, b, struct.fields, client, server
else if typeof proto == 'string' #需要重构
setTimeout stoc_follows[stoc_proto].callback, 0, b, null, client, server for key, value of constants.CTOS
if value == proto
stoc_buffer = stoc_buffer.slice(2 + stoc_message_length) proto = key
stoc_message_length = 0 break
stoc_proto = 0 throw "unknown proto" if !constants.CTOS[proto]
else
break header = new Buffer(3)
header.writeUInt16LE buffer.length + 1, 0
unless stoc_follows[stoc_proto] and stoc_follows[stoc_proto].synchronous header.writeUInt8 proto, 2
client.write data socket.write header
socket.write buffer if buffer.length
server.on "error", (e) -> console.log 'ctos_sent:', buffer if debug
console.log "server error #{e}"
client.end() #服务器端消息监听函数
server_listener = (port, client, server)->
server.on "close", (had_error) -> client.connected = true
console.log "server closed #{had_error}" console.log "connected #{port}"
client.end()
stoc_buffer = new Buffer(0)
stoc_message_length = 0
#main stoc_proto = 0
rooms = {}
rooms_port_process = {} for buffer in client.pre_connecion_buffers
#rooms_clients = {} server.write buffer
listener = net.createServer (client) -> server.on "data", (data) ->
client.connected = false console.log 'server: ', data if debug
stoc_buffer = Buffer.concat([stoc_buffer, data], stoc_buffer.length + data.length)
ctos_buffer = new Buffer(0) #buffer的错误使用方式,好孩子不要学
ctos_message_length = 0
ctos_proto = 0 while true
if stoc_message_length == 0
client.pre_connecion_buffers = new Array() if stoc_buffer.length >= 2
stoc_message_length = stoc_buffer.readUInt16LE(0)
server = new net.Socket() else
server.on "error", (e) -> break
console.log "server error #{e}" else if stoc_proto == 0
if stoc_buffer.length >= 3
client.on "data", (data) -> stoc_proto = stoc_buffer.readUInt8(2)
console.log 'client: ', data else
ctos_buffer = Buffer.concat([ctos_buffer, data], ctos_buffer.length + data.length) #buffer的错误使用方式,好孩子不要学 break
else
while true if stoc_buffer.length >= 2 + stoc_message_length
if ctos_message_length == 0 console.log constants.STOC[stoc_proto] if debug
if ctos_buffer.length >= 2 if stoc_follows[stoc_proto]
ctos_message_length = ctos_buffer.readUInt16LE(0) b = stoc_buffer.slice(3, stoc_message_length - 1 + 3)
else if struct = structs[proto_structs.STOC[constants.STOC[stoc_proto]]]
break struct._setBuff(b)
else if ctos_proto == 0 setTimeout stoc_follows[stoc_proto].callback, 0, b, struct.fields, client, server
if ctos_buffer.length >= 3 else
ctos_proto = ctos_buffer.readUInt8(2) setTimeout stoc_follows[stoc_proto].callback, 0, b, null, client, server
else
break stoc_buffer = stoc_buffer.slice(2 + stoc_message_length)
else stoc_message_length = 0
if ctos_buffer.length >= 2 + ctos_message_length stoc_proto = 0
console.log constants.CTOS[ctos_proto] else
if ctos_follows[ctos_proto] break
b = ctos_buffer.slice(3, ctos_message_length-1+3)
if struct = structs[proto_structs.CTOS[constants.CTOS[ctos_proto]]] unless stoc_follows[stoc_proto] and stoc_follows[stoc_proto].synchronous
struct._setBuff(b) client.write data
setTimeout ctos_follows[ctos_proto].callback, 0, b, struct.fields, client, server
else server.on "error", (e) ->
setTimeout ctos_follows[ctos_proto].callback, 0, b, null, client, server console.log "server error #{e}"
client.end()
ctos_buffer = ctos_buffer.slice(2 + ctos_message_length)
ctos_message_length = 0 server.on "close", (had_error) ->
ctos_proto = 0 console.log "server closed #{had_error}"
else client.end()
break
unless ctos_follows[ctos_proto] and ctos_follows[ctos_proto].synchronous #main
if client.connected listener = net.createServer (client) ->
server.write data client.connected = false
else
client.pre_connecion_buffers.push data ctos_buffer = new Buffer(0)
ctos_message_length = 0
client.on "error", (e) -> ctos_proto = 0
console.log "client error #{e}"
server.end() client.pre_connecion_buffers = new Array()
client.on "close", (had_error) -> server = new net.Socket()
console.log "client closed #{had_error}" server.on "error", (e) ->
server.end() console.log "server error #{e}"
.listen settings.port, null, null, ->
console.log "server started on #{settings.ip}:#{settings.port}" client.on "data", (data) ->
console.log 'client: ', data if debug
ctos_follow 'PLAYER_INFO', true, (buffer, info, client, server)-> ctos_buffer = Buffer.concat([ctos_buffer, data], ctos_buffer.length + data.length) #buffer的错误使用方式,好孩子不要学
client.player = info.name
while true
ctos_follow 'JOIN_GAME', false, (buffer, info, client, server)-> if ctos_message_length == 0
room_name = info.pass if ctos_buffer.length >= 2
if info.version != settings.version ctos_message_length = ctos_buffer.readUInt16LE(0)
stoc_send client, 'ERROR_MSG',{ else
msg: 4 break
code: settings.version else if ctos_proto == 0
} if ctos_buffer.length >= 3
client.end() ctos_proto = ctos_buffer.readUInt8(2)
else if !room_name.length else
stoc_send client, 'JOIN_GAME', {} break
stoc_send client, 'HS_PLAYER_ENTER', { else
name: '提示: 房间为空,请修改房间名' if ctos_buffer.length >= 2 + ctos_message_length
pos: 0 console.log constants.CTOS[ctos_proto] if debug
} if ctos_follows[ctos_proto]
else if room_name == '[INCORRECT]' #房间密码验证 b = ctos_buffer.slice(3, ctos_message_length-1+3)
stoc_send client, 'ERROR_MSG',{ if struct = structs[proto_structs.CTOS[constants.CTOS[ctos_proto]]]
msg: 1 struct._setBuff(b)
code: 1 #这返错有问题,直接双ygopro直连怎么都正常,在服务器上就经常弹不出提示 setTimeout ctos_follows[ctos_proto].callback, 0, b, struct.fields, client, server
} else
client.end() setTimeout ctos_follows[ctos_proto].callback, 0, b, null, client, server
else
if client.player != '[INCORRECT]' #用户验证 ctos_buffer = ctos_buffer.slice(2 + ctos_message_length)
if rooms[room_name] ctos_message_length = 0
if typeof rooms[room_name] == 'number' #already connected ctos_proto = 0
#rooms_clients[room_name].push client else
server.connect rooms[room_name], '127.0.0.1', -> break
server_listener(rooms[room_name], client, server)
else unless ctos_follows[ctos_proto] and ctos_follows[ctos_proto].synchronous
#rooms_clients[room_name].push client if client.connected
rooms[room_name].push client server.write data
else else
freeport (err, port)-> client.pre_connecion_buffers.push data
if rooms[room_name] #如果等freeport的时间差又来了个.....
if typeof rooms[room_name] == 'number' #already connected client.on "error", (e) ->
#rooms_clients[room_name].push client console.log "client error #{e}"
server.connect rooms[room_name], '127.0.0.1', -> server.end()
server_listener(rooms[room_name], client, server)
else client.on "close", (had_error) ->
rooms[room_name].push client console.log "client closed #{had_error}"
else server.end()
if(err) .listen settings.port, null, null, ->
stoc_send client, 'ERROR_MSG',{ console.log "server started on #{settings.ip}:#{settings.port}"
msg: 1
code: 2 ctos_follow 'PLAYER_INFO', true, (buffer, info, client, server)->
} client.player = info.name
client.end()
else ctos_follow 'JOIN_GAME', false, (buffer, info, client, server)->
rooms[room_name] = [client] room_name = info.pass
if room_name[0...2] == 'M#' if info.version != settings.version
param = [0, 0, 1, 'F', 'F', 'F', 8000, 5, 1] stoc_send client, 'ERROR_MSG',{
else if room_name[0...2] == 'T#' msg: 4
param = [0, 0, 2, 'F', 'F', 'F', 8000, 5, 1] code: settings.version
else if (param = room_name.match /^(\d)?(\d)(\d)(T|F)(T|F)(T|F)(\d+),(\d+),(\d+)/i) }
param.shift() client.end()
param[0] == parseInt(param[0]) else if !room_name.length
else stoc_send client, 'JOIN_GAME', {}
param = [0, 0, 0, 'F', 'F', 'F', 8000, 5, 1] stoc_send client, 'HS_PLAYER_ENTER', {
name: '提示: 房间为空,请修改房间名'
param.unshift port pos: 0
room = spawn './ygopro', param, cwd: 'ygocore' }
room.alive = true else if room_name == '[INCORRECT]' #房间密码验证
rooms_port_process[port] = room stoc_send client, 'ERROR_MSG',{
room.on 'exit', (code)-> msg: 1
delete rooms[room_name] code: 1 #这返错有问题,直接双ygopro直连怎么都正常,在服务器上就经常弹不出提示
delete rooms_port_process[port] }
room.stdout.once 'data', (data)-> client.end()
if(rooms[room_name]) else
rooms[room_name].forEach (c)-> if client.player != '[INCORRECT]' #用户验证
server.connect port, '127.0.0.1', -> room = Room.find_by_name(room_name)
server_listener(port, c, server) if room
rooms[room_name] = port room.add_client client
else if room.established
room.kill() server.connect room.port, '127.0.0.1', ->
else server_listener(room.port, client, server)
stoc_send client, 'ERROR_MSG',{ else
msg: 1 freeport (err, port)->
code: 2 room = Room.find_by_name(room_name)
} if room #如果等freeport的时间差又来了个.....
client.end() room.add_client client
if room.established
###################################################################################################################### server.connect room.port, '127.0.0.1', ->
server_listener(room.port, client, server)
#欢迎信息 else
stoc_follow 'JOIN_GAME', false, (buffer, info, client, server)-> if(err)
stoc_send client, 'CHAT', { stoc_send client, 'ERROR_MSG',{
player: 8 msg: 1
msg: "Mycard Debugging Server" code: 2
} }
stoc_send client, 'CHAT', { client.end()
player: 8 else
msg: "这里是测试中的新服务器, 还不稳定, 随时可能崩溃, 遇到意外请淡定\n ˉˉˉˉˉ" room = new Room(room_name, port, client)
} if room_name[0...2] == 'M#'
param = [0, 0, 1, 'F', 'F', 'F', 8000, 5, 1]
#登场台词 else if room_name[0...2] == 'T#'
taici = require './taici.json' param = [0, 0, 2, 'F', 'F', 'F', 8000, 5, 1]
stoc_follow 'GAME_MSG', false, (buffer, info, client, server)-> else if (param = room_name.match /^(\d)?(\d)(\d)(T|F)(T|F)(T|F)(\d+),(\d+),(\d+)/i)
msg = buffer.readInt8(0) param.shift()
if constants.MSG[msg] == 'SUMMONING' or constants.MSG[msg] == 'SPSUMMONING' param[0] == parseInt(param[0])
card = buffer.readUInt32LE(1) else
if taici[card] param = [0, 0, 0, 'F', 'F', 'F', 8000, 5, 1]
for line in taici[card][Math.floor(Math.random() * taici[card].length)].split("\n")
stoc_send client, 'CHAT', { param.unshift port
player: 8 process = spawn './ygopro', param, cwd: 'ygocore'
msg: line room.process = process
} process.on 'exit', (code)->
room.delete()
process.stdout.once 'data', (data)->
#stoc_follow 'HS_PLAYER_CHANGE', false, (buffer, info, client, server)-> room.established = true
# console.log 'HS_PLAYER_CHANGE', info _.each room.players, (player)->
#stoc_follow 'CHAT', false, (buffer, info, client, server)-> server.connect port, '127.0.0.1', ->
# console.log info, buffer server_listener(port, player.client, server)
else
#房间数量 stoc_send client, 'ERROR_MSG',{
http.createServer (request, response)-> msg: 1
if url.parse(request.url).pathname == '/count.json' code: 2
response.writeHead(200); }
response.end(Object.keys(rooms).length.toString()) client.end()
else
response.writeHead(404); ######################################################################################################################
response.end();
.listen settings.http_port #欢迎信息
stoc_follow 'JOIN_GAME', false, (buffer, info, client, server)->
#清理90s没活动的房间 stoc_send client, 'CHAT', {
path = require 'path' player: 8
fs = require 'fs' msg: "Mycard Debugging Server"
Inotify = require('inotify').Inotify }
stoc_send client, 'CHAT', {
inotify = new Inotify() player: 8
inotify.addWatch msg: "这里是测试中的新服务器, 还不稳定, 随时可能崩溃, 遇到意外请淡定\n ˉˉˉˉˉ"
path: 'ygocore/replay', }
watch_for: Inotify.IN_CLOSE_WRITE | Inotify.IN_CREATE | Inotify.IN_MODIFY,
callback: (event)-> #登场台词
mask = event.mask taici = require './taici.json'
if event.name stoc_follow 'GAME_MSG', false, (buffer, info, client, server)->
port = parseInt path.basename(event.name, '.yrp') msg = buffer.readInt8(0)
room = rooms_port_process[port] if constants.MSG[msg] == 'SUMMONING' or constants.MSG[msg] == 'SPSUMMONING'
if room card = buffer.readUInt32LE(1)
if mask & Inotify.IN_CREATE if taici[card]
else if mask & Inotify.IN_CLOSE_WRITE for line in taici[card][Math.floor(Math.random() * taici[card].length)].split("\n")
fs.unlink path.join('ygocore/replay'), (err)-> stoc_send client, 'CHAT', {
else if mask & Inotify.IN_MODIFY player: 8
room.alive = true msg: line
else }
console.log '[warn] event without filename'
setInterval ()-> #stoc_follow 'HS_PLAYER_CHANGE', false, (buffer, info, client, server)->
for port, room of rooms_port_process # console.log 'HS_PLAYER_CHANGE', info
if room.alive #stoc_follow 'CHAT', false, (buffer, info, client, server)->
room.alive = false # console.log info, buffer
else
console.log "killed #{port} #{room}" #房间数量
room.kill() http.createServer (request, response)->
, 900000 if url.parse(request.url).pathname == '/count.json'
response.writeHead(200);
response.end(rooms.length.toString())
else
#tip response.writeHead(404);
### response.end();
request = require 'request' .listen settings.http_port
request
url: 'https://forum.my-card.in/admin/site_contents/faq' #清理90s没活动的房间
json: true inotify = new Inotify()
, (error, response, body)-> inotify.addWatch
console.log body path: 'ygocore/replay',
watch_for: Inotify.IN_CLOSE_WRITE | Inotify.IN_CREATE | Inotify.IN_MODIFY,
stoc_follow 'DUEL_START', false, (buffer, info, client, server)-> callback: (event)->
stoc_send client, 'CHAT', { mask = event.mask
player: 8 if event.name
msg: "FAQ: 喵喵喵" port = parseInt path.basename(event.name, '.yrp')
} room = Room.find_by_port port
### if room
if mask & Inotify.IN_CREATE
### else if mask & Inotify.IN_CLOSE_WRITE
# 开包大战 fs.unlink path.join('ygocore/replay'), (err)->
else if mask & Inotify.IN_MODIFY
packs_weighted_cards = {} room.alive = true
for pack, cards of require './packs.json' else
packs_weighted_cards[pack] = [] console.log '[warn] event without filename'
for card in cards
for i in [0..card.count] setInterval ()->
packs_weighted_cards[pack].push card.card for room in rooms
if room.alive
console.log packs_weighted_cards room.alive = false
else
ctos_follow 'UPDATE_DECK', false, (buffer, info, client, server)-> console.log "kill #{port} #{room}"
ctos_send server, 'HS_NOTREADY' room.process.kill()
, 900000
deck = []
for pack in client.player
for i in [0...5]
deck.push packs_weighted_cards[pack][Math.floor(Math.random()*packs_weighted_cards[pack].length)] #tip
###
request = require 'request'
ctos_send server, 'UPDATE_DECK', { request
mainc: deck.length, url: 'https://forum.my-card.in/admin/site_contents/faq'
sidec: 0, json: true
deckbuf: deck , (error, response, body)->
} console.log body
ctos_send server, 'HS_READY'
stoc_follow 'DUEL_START', false, (buffer, info, client, server)->
### stoc_send client, 'CHAT', {
player: 8
msg: "FAQ: 喵喵喵"
}
###
###
# 开包大战
packs_weighted_cards = {}
for pack, cards of require './packs.json'
packs_weighted_cards[pack] = []
for card in cards
for i in [0..card.count]
packs_weighted_cards[pack].push card.card
console.log packs_weighted_cards
ctos_follow 'UPDATE_DECK', false, (buffer, info, client, server)->
ctos_send server, 'HS_NOTREADY'
deck = []
for pack in client.player
for i in [0...5]
deck.push packs_weighted_cards[pack][Math.floor(Math.random()*packs_weighted_cards[pack].length)]
ctos_send server, 'UPDATE_DECK', {
mainc: deck.length,
sidec: 0,
deckbuf: deck
}
ctos_send server, 'HS_READY'
###
// Generated by CoffeeScript 1.6.3 // Generated by CoffeeScript 1.6.3
(function() { (function() {
var Inotify, Struct, constants, ctos_follow, ctos_follows, ctos_send, declaration, field, freeport, fs, http, inotify, listener, name, net, path, proto_structs, result, rooms, rooms_port_process, server_listener, settings, spawn, stoc_follow, stoc_follows, stoc_send, structs, structs_declaration, taici, type, typedefs, url, _, _i, _len; var Inotify, Room, Struct, constants, ctos_follow, ctos_follows, ctos_send, debug, declaration, field, freeport, fs, http, inotify, listener, name, net, path, proto_structs, result, server_listener, settings, spawn, stoc_follow, stoc_follows, stoc_send, structs, structs_declaration, taici, type, typedefs, url, _, _i, _len;
net = require('net'); net = require('net');
...@@ -8,6 +8,10 @@ ...@@ -8,6 +8,10 @@
url = require('url'); url = require('url');
path = require('path');
fs = require('fs');
spawn = require('child_process').spawn; spawn = require('child_process').spawn;
freeport = require('freeport'); freeport = require('freeport');
...@@ -16,6 +20,8 @@ ...@@ -16,6 +20,8 @@
_ = require('underscore'); _ = require('underscore');
Inotify = require('inotify').Inotify;
structs_declaration = require('./structs.json'); structs_declaration = require('./structs.json');
typedefs = require('./typedefs.json'); typedefs = require('./typedefs.json');
...@@ -26,9 +32,59 @@ ...@@ -26,9 +32,59 @@
settings = require('./config.json'); settings = require('./config.json');
Room = (function() {
Room.all = [];
function Room(name, port, client) {
this.name = name;
this.port = port;
this.alive = true;
this.players = [];
this.add_client(client);
Room.all.push(this);
}
Room.prototype["delete"] = function(room) {
return delete Room.all[_.indexOf(Room.all, room)];
};
Room.prototype.add_client = function(client) {
return this.players.push({
client: client,
name: client.player
});
};
Room.find_by_name = function(name) {
return _.find(this.all, function(room) {
return room.name === name;
});
};
Room.find_by_port = function(port) {
return _.find(this.all, function(room) {
return room.name === port;
});
};
Room.find_by_client = function(client) {
return _.find(this.all, function(room) {
return _.some(room.players, function(player) {
return player.client === client;
});
});
};
return Room;
})();
debug = false;
if (process.argv[2] === '--debug') { if (process.argv[2] === '--debug') {
settings.port++; settings.port++;
settings.http_port++; settings.http_port++;
debug = true;
} }
structs = {}; structs = {};
...@@ -143,7 +199,9 @@ ...@@ -143,7 +199,9 @@
if (buffer.length) { if (buffer.length) {
socket.write(buffer); socket.write(buffer);
} }
return console.log('stoc_sent:', buffer); if (debug) {
return console.log('stoc_sent:', buffer);
}
}; };
ctos_send = function(socket, proto, info) { ctos_send = function(socket, proto, info) {
...@@ -178,7 +236,9 @@ ...@@ -178,7 +236,9 @@
if (buffer.length) { if (buffer.length) {
socket.write(buffer); socket.write(buffer);
} }
return console.log('ctos_sent:', buffer); if (debug) {
return console.log('ctos_sent:', buffer);
}
}; };
server_listener = function(port, client, server) { server_listener = function(port, client, server) {
...@@ -195,7 +255,9 @@ ...@@ -195,7 +255,9 @@
} }
server.on("data", function(data) { server.on("data", function(data) {
var b, struct; var b, struct;
console.log('server: ', data); if (debug) {
console.log('server: ', data);
}
stoc_buffer = Buffer.concat([stoc_buffer, data], stoc_buffer.length + data.length); stoc_buffer = Buffer.concat([stoc_buffer, data], stoc_buffer.length + data.length);
while (true) { while (true) {
if (stoc_message_length === 0) { if (stoc_message_length === 0) {
...@@ -212,7 +274,9 @@ ...@@ -212,7 +274,9 @@
} }
} else { } else {
if (stoc_buffer.length >= 2 + stoc_message_length) { if (stoc_buffer.length >= 2 + stoc_message_length) {
console.log(constants.STOC[stoc_proto]); if (debug) {
console.log(constants.STOC[stoc_proto]);
}
if (stoc_follows[stoc_proto]) { if (stoc_follows[stoc_proto]) {
b = stoc_buffer.slice(3, stoc_message_length - 1 + 3); b = stoc_buffer.slice(3, stoc_message_length - 1 + 3);
if (struct = structs[proto_structs.STOC[constants.STOC[stoc_proto]]]) { if (struct = structs[proto_structs.STOC[constants.STOC[stoc_proto]]]) {
...@@ -244,10 +308,6 @@ ...@@ -244,10 +308,6 @@
}); });
}; };
rooms = {};
rooms_port_process = {};
listener = net.createServer(function(client) { listener = net.createServer(function(client) {
var ctos_buffer, ctos_message_length, ctos_proto, server; var ctos_buffer, ctos_message_length, ctos_proto, server;
client.connected = false; client.connected = false;
...@@ -261,7 +321,9 @@ ...@@ -261,7 +321,9 @@
}); });
client.on("data", function(data) { client.on("data", function(data) {
var b, struct; var b, struct;
console.log('client: ', data); if (debug) {
console.log('client: ', data);
}
ctos_buffer = Buffer.concat([ctos_buffer, data], ctos_buffer.length + data.length); ctos_buffer = Buffer.concat([ctos_buffer, data], ctos_buffer.length + data.length);
while (true) { while (true) {
if (ctos_message_length === 0) { if (ctos_message_length === 0) {
...@@ -278,7 +340,9 @@ ...@@ -278,7 +340,9 @@
} }
} else { } else {
if (ctos_buffer.length >= 2 + ctos_message_length) { if (ctos_buffer.length >= 2 + ctos_message_length) {
console.log(constants.CTOS[ctos_proto]); if (debug) {
console.log(constants.CTOS[ctos_proto]);
}
if (ctos_follows[ctos_proto]) { if (ctos_follows[ctos_proto]) {
b = ctos_buffer.slice(3, ctos_message_length - 1 + 3); b = ctos_buffer.slice(3, ctos_message_length - 1 + 3);
if (struct = structs[proto_structs.CTOS[constants.CTOS[ctos_proto]]]) { if (struct = structs[proto_structs.CTOS[constants.CTOS[ctos_proto]]]) {
...@@ -321,7 +385,7 @@ ...@@ -321,7 +385,7 @@
}); });
ctos_follow('JOIN_GAME', false, function(buffer, info, client, server) { ctos_follow('JOIN_GAME', false, function(buffer, info, client, server) {
var room_name; var room, room_name;
room_name = info.pass; room_name = info.pass;
if (info.version !== settings.version) { if (info.version !== settings.version) {
stoc_send(client, 'ERROR_MSG', { stoc_send(client, 'ERROR_MSG', {
...@@ -343,24 +407,24 @@ ...@@ -343,24 +407,24 @@
return client.end(); return client.end();
} else { } else {
if (client.player !== '[INCORRECT]') { if (client.player !== '[INCORRECT]') {
if (rooms[room_name]) { room = Room.find_by_name(room_name);
if (typeof rooms[room_name] === 'number') { if (room) {
return server.connect(rooms[room_name], '127.0.0.1', function() { room.add_client(client);
return server_listener(rooms[room_name], client, server); if (room.established) {
return server.connect(room.port, '127.0.0.1', function() {
return server_listener(room.port, client, server);
}); });
} else {
return rooms[room_name].push(client);
} }
} else { } else {
return freeport(function(err, port) { return freeport(function(err, port) {
var param, room; var param, process;
if (rooms[room_name]) { room = Room.find_by_name(room_name);
if (typeof rooms[room_name] === 'number') { if (room) {
return server.connect(rooms[room_name], '127.0.0.1', function() { room.add_client(client);
return server_listener(rooms[room_name], client, server); if (room.established) {
return server.connect(room.port, '127.0.0.1', function() {
return server_listener(room.port, client, server);
}); });
} else {
return rooms[room_name].push(client);
} }
} else { } else {
if (err) { if (err) {
...@@ -370,7 +434,7 @@ ...@@ -370,7 +434,7 @@
}); });
return client.end(); return client.end();
} else { } else {
rooms[room_name] = [client]; room = new Room(room_name, port, client);
if (room_name.slice(0, 2) === 'M#') { if (room_name.slice(0, 2) === 'M#') {
param = [0, 0, 1, 'F', 'F', 'F', 8000, 5, 1]; param = [0, 0, 1, 'F', 'F', 'F', 8000, 5, 1];
} else if (room_name.slice(0, 2) === 'T#') { } else if (room_name.slice(0, 2) === 'T#') {
...@@ -382,26 +446,20 @@ ...@@ -382,26 +446,20 @@
param = [0, 0, 0, 'F', 'F', 'F', 8000, 5, 1]; param = [0, 0, 0, 'F', 'F', 'F', 8000, 5, 1];
} }
param.unshift(port); param.unshift(port);
room = spawn('./ygopro', param, { process = spawn('./ygopro', param, {
cwd: 'ygocore' cwd: 'ygocore'
}); });
room.alive = true; room.process = process;
rooms_port_process[port] = room; process.on('exit', function(code) {
room.on('exit', function(code) { return room["delete"]();
delete rooms[room_name];
return delete rooms_port_process[port];
}); });
return room.stdout.once('data', function(data) { return process.stdout.once('data', function(data) {
if (rooms[room_name]) { room.established = true;
rooms[room_name].forEach(function(c) { return _.each(room.players, function(player) {
return server.connect(port, '127.0.0.1', function() { return server.connect(port, '127.0.0.1', function() {
return server_listener(port, c, server); return server_listener(port, player.client, server);
});
}); });
return rooms[room_name] = port; });
} else {
return room.kill();
}
}); });
} }
} }
...@@ -453,19 +511,13 @@ ...@@ -453,19 +511,13 @@
http.createServer(function(request, response) { http.createServer(function(request, response) {
if (url.parse(request.url).pathname === '/count.json') { if (url.parse(request.url).pathname === '/count.json') {
response.writeHead(200); response.writeHead(200);
return response.end(Object.keys(rooms).length.toString()); return response.end(rooms.length.toString());
} else { } else {
response.writeHead(404); response.writeHead(404);
return response.end(); return response.end();
} }
}).listen(settings.http_port); }).listen(settings.http_port);
path = require('path');
fs = require('fs');
Inotify = require('inotify').Inotify;
inotify = new Inotify(); inotify = new Inotify();
inotify.addWatch({ inotify.addWatch({
...@@ -476,7 +528,7 @@ ...@@ -476,7 +528,7 @@
mask = event.mask; mask = event.mask;
if (event.name) { if (event.name) {
port = parseInt(path.basename(event.name, '.yrp')); port = parseInt(path.basename(event.name, '.yrp'));
room = rooms_port_process[port]; room = Room.find_by_port(port);
if (room) { if (room) {
if (mask & Inotify.IN_CREATE) { if (mask & Inotify.IN_CREATE) {
...@@ -493,15 +545,15 @@ ...@@ -493,15 +545,15 @@
}); });
setInterval(function() { setInterval(function() {
var port, room, _results; var room, _j, _len1, _results;
_results = []; _results = [];
for (port in rooms_port_process) { for (_j = 0, _len1 = rooms.length; _j < _len1; _j++) {
room = rooms_port_process[port]; room = rooms[_j];
if (room.alive) { if (room.alive) {
_results.push(room.alive = false); _results.push(room.alive = false);
} else { } else {
console.log("killed " + port + " " + room); console.log("kill " + port + " " + room);
_results.push(room.kill()); _results.push(room.process.kill());
} }
} }
return _results; return _results;
......
...@@ -6,5 +6,5 @@ ...@@ -6,5 +6,5 @@
"ygopro-server.coffee" "ygopro-server.coffee"
], ],
"names": [], "names": [],
"mappings": "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" "mappings": ";AACA;CAAA,KAAA,yTAAA;;CAAA,CAAA,CAAA,EAAM,EAAA;;CAAN,CACA,CAAO,CAAP,EAAO,CAAA;;CADP,CAEA,CAAA,EAAM,EAAA;;CAFN,CAGA,CAAO,CAAP,EAAO,CAAA;;CAHP,CAIA,CAAK,CAAA,GAAA;;CAJL,CAKA,CAAQ,EAAR,EAAQ,QAAA;;CALR,CAQA,CAAW,IAAA,CAAX,EAAW;;CARX,CASA,CAAS,GAAT,CAAS,CAAA;;CATT,CAUA,CAAI,IAAA,KAAA;;CAVJ,CAWA,CAAU,IAAV,EAAU;;CAXV,CAcA,CAAsB,IAAA,SAAA,GAAtB;;CAdA,CAeA,CAAW,IAAA,CAAX,SAAW;;CAfX,CAgBA,CAAgB,IAAA,MAAhB,SAAgB;;CAhBhB,CAiBA,CAAY,IAAA,EAAZ,SAAY;;CAjBZ,CAoBA,CAAW,IAAA,CAAX,OAAW;;CApBX,CAsBM;CACJ,CAAA,CAAA,CAAA;;CAQa,CAAO,CAAP,CAAA,EAAA,QAAC;CACZ,EAAQ,CAAP,EAAD;CAAA,EACQ,CAAP,EAAD;CADA,EAES,CAAR,CAAD,CAAA;CAFA,CAAA,CAGW,CAAV,EAAD,CAAA;CAHA,GAIC,EAAD,IAAA;CAJA,EAKQ,CAAJ,EAAJ;CAdF,IAQa;;CARb,EAgBQ,CAAA,KAAC;AACP,CAAA,CAAoC,CAApB,CAAL,EAAX,CAAgB,MAAhB;CAjBF,IAgBQ;;CAhBR,EAmBY,GAAA,GAAC,CAAb;CACG,GAAA,GAAO,MAAR;CAAc,CAAS,IAAR,EAAA;CAAD,CAAuB,EAAN,EAAY,EAAZ;CADrB,OACV;CApBF,IAmBY;;CAnBZ,EAwBe,CAAf,KAAgB,GAAhB;CACG,CAAY,CAAb,CAAA,KAAc,IAAd;CACO,GAAD,CAAS,UAAb;CADF,MAAa;CAzBf,IAwBe;;CAxBf,EA2Be,CAAf,KAAgB,GAAhB;CACG,CAAY,CAAb,CAAA,KAAc,IAAd;CACO,GAAD,CAAS,UAAb;CADF,MAAa;CA5Bf,IA2Be;;CA3Bf,EA8BiB,CAAjB,EAAiB,GAAC,KAAlB;CACG,CAAY,CAAb,CAAA,KAAc,IAAd;CACG,CAAoB,CAAA,CAArB,EAAqB,CAArB,EAAsB,MAAtB;CACS,IAAU,CAAX,WAAN;CADF,QAAqB;CADvB,MAAa;CA/Bf,IA8BiB;;CA9BjB;;CAvBF;;CAAA,CA8DA,CAAQ,EAAR;;CACA,CAAA,EAAG,CAAmB,EAAZ,EAAV;AACE,CAAA,CAAA,EAAA,IAAQ;AACR,CADA,CAAA,EACA,IAAQ,CAAR;CADA,EAEQ,CAAR,CAAA;IAlEF;;CAAA,CAqEA,CAAU,IAAV;;AACA,CAAA,MAAA,oBAAA;6CAAA;CACE,EAAS,CAAT,EAAA;AACA,CAAA,QAAA,yCAAA;+BAAA;CACE,GAAG,CAAK,CAAR,EAAA;CACE,IAAY,GAAZ,QAAO;CAAP,SAAA,KACO;CAAgB,CAAyB,CAAa,CAAtC,CAAA,CAAM,EAAN,IAAA;CAAhB;CADP;CAEO,EAA8B,CAAI,IAAlC,UAAO,MAAA;CAFd,QADF;MAAA,EAAA;CAKE,EAAO,CAAP,CAAY,GAAZ;CACA,GAAyB,IAAzB;CAAA,EAAO,CAAP,IAAgB,EAAhB;UADA;CAEA,GAAG,CAAK,CAAR,EAAA;CACE,CAAyB,EAAzB,CAAA,CAAM,IAAN;MADF,IAAA;CAGE,GAAG,GAAQ,GAAX;CACE,CAA0B,EAA1B,CAAmB,CAAb,CAA4B,KAAlC;MADF,MAAA;CAGE,GAAO,CAAW,CAAX,MAAP;YANJ;UAPF;QADF;CAAA,IADA;CAAA,EAgBgB,CAAhB,EAhBA,CAgBQ;CAjBV,EAtEA;;CAAA,CA2FA,CAAe,SAAf;;CA3FA,CA4FA,CAAe,SAAf;;CA5FA,CA6FA,CAAc,EAAA,GAAA,CAAC,EAAf;CACE,OAAA,QAAA;AAAG,CAAH,GAAA,CAAG,CAAA,EAAH;CACE;CAAA,UAAA;2BAAA;CACE,GAAG,CAAA,GAAH;CACE,EAAQ,EAAR,KAAA;CACA,eAFF;UADF;CAAA,MAAA;AAI0B,CAA1B,GAAyB,CAAgB,CAAzC,GAAmC;CAAnC,aAAM,CAAN;QALF;MAAA;CAMa,EAAS,EAAT,MAAb,CAAa;CAAS,CAAW,IAAV,EAAA;CAAD,CAAkC,IAAb,KAAA;CAP/B;CA7Fd,EA6Fc;;CA7Fd,CAqGA,CAAc,EAAA,GAAA,CAAC,EAAf;CACE,OAAA,QAAA;AAAG,CAAH,GAAA,CAAG,CAAA,EAAH;CACE;CAAA,UAAA;2BAAA;CACE,GAAG,CAAA,GAAH;CACE,EAAQ,EAAR,KAAA;CACA,eAFF;UADF;CAAA,MAAA;AAI0B,CAA1B,GAAyB,CAAgB,CAAzC,GAAmC;CAAnC,aAAM,CAAN;QALF;MAAA;CAMa,EAAS,EAAT,MAAb,CAAa;CAAS,CAAW,IAAV,EAAA;CAAD,CAAkC,IAAb,KAAA;CAP/B;CArGd,EAqGc;;CArGd,CAgHA,CAAY,CAAA,CAAA,CAAA,GAAZ;CAGE,OAAA,gCAAA;AAAG,CAAH,GAAA,CAAkB,CAAf,KAAH;CACE,CAAA,CAAS,GAAT;CACa,GAAP,EAFR,EAEQ;CACN,EAAS,CAAT,EAAA;MAHF;CAKE,EAAS,CAA2B,CAAA,CAApC,CAAiB,MAAa;CAA9B,KACA,EAAA;CADA,EAEA,CAAA,EAAA;CAFA,EAGS,GAAT;MARF;AAUG,CAAH,GAAA,CAAG,CAAA,EAAH;CACE;CAAA,UAAA;2BAAA;CACE,GAAG,CAAA,GAAH;CACE,EAAQ,EAAR,KAAA;CACA,eAFF;UADF;CAAA,MAAA;AAI0B,CAA1B,GAAyB,CAAgB,CAAzC,GAAmC;CAAnC,aAAM,CAAN;QALF;MAVA;CAAA,EAiBa,CAAb,EAAA;CAjBA,CAkBwC,CAAH,CAArC,EAAM,OAAN;CAlBA,CAmByB,EAAzB,CAAA,CAAM,IAAN;CAnBA,GAoBA,CAAA,CAAM;CACN,GAAA,EAA6B;CAA7B,IAAA,CAAA;MArBA;CAsBA,GAAA,CAAA;CAAQ,CAAkB,CAA1B,GAAA,CAAO,KAAP,CAAA;MAzBU;CAhHZ,EAgHY;;CAhHZ,CA2IA,CAAY,CAAA,CAAA,CAAA,GAAZ;CAGE,OAAA,gCAAA;AAAG,CAAH,GAAA,CAAkB,CAAf,KAAH;CACE,CAAA,CAAS,GAAT;CACa,GAAP,EAFR,EAEQ;CACN,EAAS,CAAT,EAAA;MAHF;CAKE,EAAS,CAA2B,CAAA,CAApC,CAAiB,MAAa;CAA9B,KACA,EAAA;CADA,EAEA,CAAA,EAAA;CAFA,EAGS,GAAT;MARF;AAUG,CAAH,GAAA,CAAG,CAAA,EAAH;CACE;CAAA,UAAA;2BAAA;CACE,GAAG,CAAA,GAAH;CACE,EAAQ,EAAR,KAAA;CACA,eAFF;UADF;CAAA,MAAA;AAI0B,CAA1B,GAAyB,CAAgB,CAAzC,GAAmC;CAAnC,aAAM,CAAN;QALF;MAVA;CAAA,EAiBa,CAAb,EAAA;CAjBA,CAkBwC,CAAH,CAArC,EAAM,OAAN;CAlBA,CAmByB,EAAzB,CAAA,CAAM,IAAN;CAnBA,GAoBA,CAAA,CAAM;CACN,GAAA,EAA6B;CAA7B,IAAA,CAAA;MArBA;CAsBA,GAAA,CAAA;CAAQ,CAAkB,CAA1B,GAAA,CAAO,KAAP,CAAA;MAzBU;CA3IZ,EA2IY;;CA3IZ,CAuKA,CAAkB,CAAA,EAAA,GAAC,MAAnB;CACE,OAAA,6DAAA;CAAA,EAAmB,CAAnB,EAAM,GAAN;CAAA,EACA,CAAA,GAAO,KAAM;CADb,EAGkB,CAAlB,EAAkB,KAAlB;CAHA,EAIsB,CAAtB,eAAA;CAJA,EAKa,CAAb,MAAA;CAEA;CAAA,QAAA,oCAAA;yBAAA;CACE,IAAA,CAAA;CADF,IAPA;CAAA,CAUA,CAAkB,CAAlB,EAAM,GAAa;CACjB,QAAA,CAAA;CAAA,GAAgC,CAAhC,CAAA;CAAA,CAAwB,CAAxB,CAAA,GAAO,CAAP,EAAA;QAAA;CAAA,CAC0C,CAA5B,CAAc,EAA5B,KAAA;CAGA,EAAA,CAAA,SAAM;CACJ,GAAG,CAAuB,GAA1B,WAAG;CACD,GAAG,EAAA,IAAH,CAAc;CACZ,EAAsB,QAAW,CAAjC,OAAA;MADF,MAAA;CAGE,iBAHF;YADF;CAAA,GAKQ,CAAc,CALtB,IAAA;CAME,GAAG,EAAA,IAAH,CAAc;CACZ,EAAa,MAAA,CAAb,CAAwB,CAAxB;MADF,MAAA;CAGE,iBAHF;YANF;MAAA,IAAA;CAWE,EAA6B,CAA1B,EAAA,IAAH,CAAc,QAAd;CACE,GAA0C,CAA1C,OAAA;CAAA,EAAA,CAA2B,GAApB,EAAc,CAAM,IAA3B;cAAA;CACA,GAAG,MAAa,EAAhB;CACE,CAAyB,CAArB,EAAA,MAAW,GAAf,KAAyB;CACzB,EAAY,CAAT,EAAA,CAAiB,EAA4B,CAAM,GAArB,CAAjC;CACE,KAAM,EAAN,QAAA;CAAA,CAC8C,IAAY,EAA1D,EAAA,EAAwB,IAAxB;MAFF,UAAA;CAIE,CAA8C,EAA9C,EAAA,EAAA,EAAA,EAAwB,IAAxB;gBANJ;cADA;CAAA,EASc,EAAA,MAAd,CAAA,OAAc;CATd,EAUsB,SAAtB,OAAA;CAVA,EAWa,OAAb,EAAA;MAZF,MAAA;CAcE,iBAdF;YAXF;UADF;CAJA,MAIA;AA4BA,CAAA,GAAA,EAAA,IAAoB,CAApB,CAAoB;CACX,GAAP,CAAA,CAAM,SAAN;QAlCc;CAAlB,IAAkB;CAVlB,CA8CA,CAAmB,CAAnB,EAAM,CAAN,EAAoB;CAClB,EAAA,GAAA,CAAO,QAAM;CACN,EAAP,GAAM,OAAN;CAFF,IAAmB;CAIZ,CAAP,CAAmB,GAAb,CAAN,EAAoB,EAApB;CACE,EAAA,GAAA,CAAO,EAAP,OAAa;CACN,EAAP,GAAM,OAAN;CAFF,IAAmB;CA1NrB,EAuKkB;;CAvKlB,CAgOA,CAAW,GAAiB,EAA5B,CAA6B,GAAlB;CACT,OAAA,4CAAA;CAAA,EAAmB,CAAnB,CAAA,CAAM,GAAN;CAAA,EAEkB,CAAlB,EAAkB,KAAlB;CAFA,EAGsB,CAAtB,eAAA;CAHA,EAIa,CAAb,MAAA;CAJA,EAMmC,CAAnC,CAAmC,CAA7B,eAAN;CANA,EAQa,CAAb,EAAA;CARA,CASA,CAAmB,CAAnB,EAAM,CAAN,EAAoB;CACV,EAAR,IAAO,MAAP,EAAa;CADf,IAAmB;CATnB,CAYA,CAAkB,CAAlB,EAAM,GAAa;CACjB,QAAA,CAAA;CAAA,GAAgC,CAAhC,CAAA;CAAA,CAAwB,CAAxB,CAAA,GAAO,CAAP,EAAA;QAAA;CAAA,CAC0C,CAA5B,CAAc,EAA5B,KAAA;CAEA,EAAA,CAAA,SAAM;CACJ,GAAG,CAAuB,GAA1B,WAAG;CACD,GAAG,EAAA,IAAH,CAAc;CACZ,EAAsB,QAAW,CAAjC,OAAA;MADF,MAAA;CAGE,iBAHF;YADF;CAAA,GAKQ,CAAc,CALtB,IAAA;CAME,GAAG,EAAA,IAAH,CAAc;CACZ,EAAa,MAAA,CAAb,CAAwB,CAAxB;MADF,MAAA;CAGE,iBAHF;YANF;MAAA,IAAA;CAWE,EAA6B,CAA1B,EAAA,IAAH,CAAc,QAAd;CACE,GAA0C,CAA1C,OAAA;CAAA,EAAA,CAA2B,GAApB,EAAc,CAAM,IAA3B;cAAA;CACA,GAAG,MAAa,EAAhB;CACE,CAAyB,CAArB,EAAA,MAAW,GAAf,KAAyB;CACzB,EAAY,CAAT,EAAA,CAAiB,EAA4B,CAAM,GAArB,CAAjC;CACE,KAAM,EAAN,QAAA;CAAA,CAC8C,IAAY,EAA1D,EAAA,EAAwB,IAAxB;MAFF,UAAA;CAIE,CAA8C,EAA9C,EAAA,EAAA,EAAA,EAAwB,IAAxB;gBANJ;cADA;CAAA,EASc,EAAA,MAAd,CAAA,OAAc;CATd,EAUsB,SAAtB,OAAA;CAVA,EAWa,OAAb,EAAA;MAZF,MAAA;CAcE,iBAdF;YAXF;UADF;CAHA,MAGA;AA4BA,CAAA,GAAA,EAAA,IAAoB,CAApB,CAAoB;CAClB,GAAG,EAAM,EAAT,CAAA;CACS,GAAP,CAAA,CAAM,WAAN;MADF,IAAA;CAGS,GAAP,EAAM,WAAN,IAA4B;UAJhC;QAhCgB;CAAlB,IAAkB;CAZlB,CAkDA,CAAmB,CAAnB,EAAM,CAAN,EAAoB;CAClB,EAAA,GAAA,CAAO,QAAM;CACN,EAAP,GAAM,OAAN;CAFF,IAAmB;CAIZ,CAAP,CAAmB,GAAb,CAAN,EAAoB,EAApB;CACE,EAAA,GAAA,CAAO,EAAP,OAAa;CACN,EAAP,GAAM,OAAN;CAFF,IAAmB;CAvDV,CA0DY,CA1DK,CAAjB,EAAA,EA0DK,CAAmB;CACzB,CAAK,CAAb,CAAA,GAAO,CAAiC,GAAxC,SAAa;CA3DJ,EA0DwB;;CA1RnC,CA6RA,CAAiC,CAAjC,EAAiC,GAAC,EAAlC,EAAA;CACS,EAAS,CAAI,EAAd,KAAN;CADF,EAAiC;;CA7RjC,CAgSA,CAAgC,CAAA,CAAhC,CAAgC,GAAC,EAAjC;CACE,OAAA,OAAA;CAAA,EAAY,CAAZ,KAAA;CACA,GAAA,CAAmB,EAAhB,CAAwB;CACzB,CAAkB,IAAlB,GAAA,EAAA;CAA8B,CACvB,CAAL,KAAA;CAD4B,CAEtB,EAAN,GAF4B,CAE5B;CAFF,OAAA;CAIO,EAAP,GAAM,OAAN;AACO,CAAD,GAAA,EANR,GAMkB;CAChB,CAAkB,IAAlB,GAAA,EAAA;CACU,CAAQ,IAAlB,GAAA,IAAA,IAAA;CAAqC,CAC7B,EAAN,IAAA,SADmC;CAAA,CAE9B,CAAL,KAAA;CAVJ,OAQE;IAIM,CAAa,CAZrB,GAYQ,IAZR;CAaE,CAAkB,IAAlB,GAAA,EAAA;CAA8B,CACvB,CAAL,KAAA;CAD4B,CAEtB,EAAN,IAAA;CAFF,OAAA;CAIO,EAAP,GAAM,OAAN;MAjBF;CAmBE,GAAG,CAAiB,CAApB,OAAA;CACE,EAAO,CAAP,IAAA,CAAO,GAAA;CACP,GAAG,IAAH;CACE,GAAI,EAAJ,IAAA;CACA,GAAG,MAAH,CAAA;CACS,CAAmB,CAAa,CAApB,EAAb,CAAN,EAAuC,EAAvC,QAAA;CACkB,CAAW,EAAP,EAApB,SAAA,MAAA;CADF,YAAuC;YAH3C;MAAA,IAAA;CAMW,CAAM,CAAN,CAAA,IAAT,CAAU,QAAV;CACE,aAAA,EAAA;CAAA,EAAO,CAAP,KAAO,GAAP;CACA,GAAG,QAAH;CACE,GAAI,EAAJ,IAAA,IAAA;CACA,GAAG,OAAH,GAAA;CACS,CAAmB,CAAa,CAApB,EAAb,CAAN,EAAuC,EAAvC,YAAA;CACkB,CAAW,EAAP,EAApB,SAAA,UAAA;CADF,gBAAuC;gBAH3C;MAAA,QAAA;CAME,EAAA,CAAG,UAAH;CACE,CAAkB,IAAlB,GAAA,EAAA,KAAA;CAA8B,CACvB,CAAL,eAAA;CAD4B,CAEtB,EAAN,cAAA;CAFF,iBAAA;CAIO,EAAP,GAAM,iBAAN;MALF,UAAA;CAOE,CAA2B,CAAhB,CAAX,EAAW,GAAA,OAAX;CACA,GAAG,CAAoB,IAAV,GAAV,IAAH;CACE,CAAY,CAAJ,CAAA,CAAR,aAAA;IACM,CAAoB,CAF5B,GAEkB,GAAV,MAFR;CAGE,CAAY,CAAJ,CAAA,CAAR,aAAA;CACO,EAAQ,CAAT,CAAC,CAJT,GAI0B,SAJ1B,+BAIiB;CACf,IAAK,aAAL;CAAA,IACM,GAAM,UAAZ;MANF,YAAA;CAQE,CAAY,CAAJ,CAAA,CAAR,aAAA;kBATF;CAAA,GAWA,CAAK,EAAL,SAAA;CAXA,CAY4B,CAAlB,EAAA,EAAV,GAAU,MAAV;CAAmC,CAAK,CAAL,MAAA,SAAA;CAZnC,iBAYU;CAZV,EAae,CAAX,GAAJ,SAAA;CAbA,CAcA,CAAmB,CAAA,EAAnB,CAAO,EAAa,OAApB;CACO,GAAD,IAAA,iBAAJ;CADF,gBAAmB;CAEX,CAAoB,CAAA,CAA5B,EAAc,CAAP,EAAsB,cAA7B;CACE,EAAmB,CAAf,OAAJ,OAAA;CACC,CAAoB,CAAA,CAArB,EAAqB,CAArB,EAAsB,gBAAtB;CACS,CAAc,CAAa,CAAlC,EAAM,CAAN,EAAkC,EAAlC,gBAAA;CACkB,CAAM,EAAtB,EAA4B,SAA5B,cAAA;CADF,oBAAkC;CADpC,kBAAqB;CAFvB,gBAA4B;gBA7BhC;cAFO;CAAT,UAAS;UARb;MAAA,EAAA;CA6CE,CAAkB,IAAlB,EAAA,CAAA,EAAA;CAA8B,CACvB,CAAL,OAAA;CAD4B,CAEtB,EAAN,MAAA;CAFF,SAAA;CAIO,EAAP,GAAM,SAAN;QApEJ;MAF8B;CAAhC,EAAgC;;CAhShC,CA2WA,CAAgC,CAAA,CAAhC,CAAgC,GAAC,EAAjC;CACE,CAAkB,EAAlB,EAAA,GAAA;CAA0B,CAChB,IAAR;CADwB,CAEnB,CAAL,GAAA,mBAFwB;CAA1B,KAAA;CAIU,CAAQ,IAAlB,GAAA,EAAA;CAA0B,CAChB,IAAR;CADwB,CAEnB,CAAL,GAAA,gEAFwB;CALI,KAK9B;CALF,EAAgC;;CA3WhC,CAsXA,CAAQ,EAAR,EAAQ,OAAA;;CAtXR,CAuXA,CAA+B,CAAA,CAA/B,CAA+B,GAAC,CAAhC,CAAA;CACE,OAAA,kCAAA;CAAA,EAAA,CAAA,EAAY,EAAN;CACN,EAAiB,CAAjB,CAAyB,IAAb,EAAT,EAAH;CACE,EAAO,CAAP,EAAA,MAAO;CACP,GAAG,CAAM,CAAT;CACE;CAAA;cAAA,+BAAA;2BAAA;CACE,CAAkB,IAAlB,GAAA;CAA0B,CAChB,IAAR,MAAA;CADwB,CAElB,CAAN,CAFwB,QAExB;CAFF,WAAA;CADF;yBADF;QAFF;MAF6B;CAA/B,EAA+B;;CAvX/B,CAyYA,CAAkB,CAAd,GAAc,CAAA,CAAC,GAAnB;CACE,EAAM,CAAN,CAAG,EAAiB,CAAjB,KAAH;CACE,EAAA,GAAA,EAAQ,CAAR;CACS,EAAT,EAAkB,CAAO,EAAjB,KAAR;MAFF;CAIE,EAAA,GAAA,EAAQ,CAAR;CACS,EAAT,KAAQ,KAAR;MANc;CAAlB,EAAkB,GAAlB,EAOgB,CAPhB;;CAzYA,CAmZA,CAAc,CAAA,GAAd;;CAnZA,CAoZA,KAAO,CAAP;CACE,CAAM,EAAN,YAAA;CAAA,CACW,CAAyB,CAApC,GAAkB,EAAlB,KAAW;CADX,CAEU,CAAA,CAAV,CAAU,GAAV,CAAW;CACT,SAAA,MAAA;CAAA,EAAO,CAAP,CAAY,CAAZ;CACA,GAAG,CAAK,CAAR;CACE,CAA0C,CAAnC,CAAP,CAAmC,CAAnB,EAAhB;CAAA,EACO,CAAP,IAAA,IAAO;CACP,GAAG,IAAH;CACE,EAAU,CAAP,GAAc,EAAjB,CAAA;CAAA;CACuB,EAAR,CAAP,EADR,CACsB,KADtB,EAAA;CAEK,CAAD,CAAqC,CAAzB,EAAd,GAAwC,OAA9B,GAAV;CACqB,EAAR,CAAP,EAHR,CAGsB,EAHtB,GAAA;CAIO,EAAQ,CAAT,CAAJ,cAAA;YALJ;UAHF;MAAA,EAAA;CAUU,EAAR,IAAO,QAAP,gBAAA;QAZM;CAFV,IAEU;CAvZZ,GAoZA;;CApZA,CAqaA,CAAY,MAAA,EAAZ;CACE,OAAA,iBAAA;AAAA,CAAA;UAAA,oCAAA;wBAAA;CACE,GAAG,CAAH,CAAA;CACE,EAAa,CAAT,CAAJ;MADF,EAAA;CAGE,EAAA,CAAa,GAAN,CAAP;CAAA,GACI,GAAQ;QALhB;CAAA;qBADU;CAAZ,CAOE,CAPU,GAAZ;;CAYA;;;;;;;;;;;;;;CAjbA;;CAgcA;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAhcA;CAAA"
} }
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment