Commit 42ae911a authored by mercury233's avatar mercury233

full of bug

parent 098a4dfa
......@@ -16,7 +16,7 @@
"underscore": "*",
"underscore.string": "*",
"request": "*",
"bunyan": "*",
"bunyan": "*"
},
"license": "GPLv3",
"main": "ygopro-server.js",
......
......@@ -83,7 +83,7 @@ class Room
@process = spawn './ygopro', param, cwd: 'ygocore'
@process.on 'exit', (code)=>
#log.info 'room-exit', this.name, this.port, code
@disconnector = 'server' unless @disconnector
@process = null
this.delete()
@process.stdout.setEncoding('utf8')
@process.stdout.once 'data', (data)=>
......@@ -91,7 +91,10 @@ class Room
@port = parseInt data
_.each @players, (player)=>
player.server.connect @port, '127.0.0.1',=>
player.server.write buffer for buffer in player.pre_establish_buffers
for buffer in player.pre_establish_buffers
player.buffer=buffer
buffer=null
player.server.write player.buffer
player.established = true
delete: ->
......@@ -107,7 +110,10 @@ class Room
if @established
client.server.connect @port, '127.0.0.1', ->
client.server.write buffer for buffer in client.pre_establish_buffers
for buffer in client.pre_establish_buffers
client.buffer=buffer
buffer=null
client.server.write client.buffer
client.established = true
disconnect: (client, error)->
......@@ -121,7 +127,7 @@ class Room
if @players.length
ygopro.stoc_send_chat_to_room this, "#{client.name} #{'离开了游戏'}#{if error then ": #{error}" else ''}"
else
@process.kill()
@process.kill() if @process
this.delete()
module.exports = Room
\ No newline at end of file
......@@ -99,9 +99,7 @@
});
this.process.on('exit', (function(_this) {
return function(code) {
if (!_this.disconnector) {
_this.disconnector = 'server';
}
_this.process = null;
return _this["delete"]();
};
})(this));
......@@ -116,7 +114,9 @@
ref = player.pre_establish_buffers;
for (i = 0, len = ref.length; i < len; i++) {
buffer = ref[i];
player.server.write(buffer);
player.buffer = buffer;
buffer = null;
player.server.write(player.buffer);
}
return player.established = true;
});
......@@ -148,7 +148,9 @@
ref = client.pre_establish_buffers;
for (i = 0, len = ref.length; i < len; i++) {
buffer = ref[i];
client.server.write(buffer);
client.buffer = buffer;
buffer = null;
client.server.write(client.buffer);
}
return client.established = true;
});
......@@ -171,7 +173,9 @@
if (this.players.length) {
return ygopro.stoc_send_chat_to_room(this, client.name + " " + '离开了游戏' + (error ? ": " + error : ''));
} else {
this.process.kill();
if (this.process) {
this.process.kill();
}
return this["delete"]();
}
}
......
......@@ -27,6 +27,8 @@ settings = require './config.json'
ygopro = require './ygopro.js'
Room = require './room.js'
#连接池
sockets = []
#debug模式 端口号+1
debug = false
......@@ -42,120 +44,147 @@ else
net.createServer (client) ->
server = new net.Socket()
client.server = server
#释放处理
client.on 'close', (had_error) ->
log.info "client closed", client.name, had_error
unless client.closed
sockets.push client
sockets.push server
client.setTimeout(200000)
client.bye = () ->
unless !client || client.closed
client.closed = true
client.room.disconnect(client) if client.room
server.end()
client.on 'error', (error)->
log.info "client error", client.name, error
unless client.closed
client.closed = error
client.room.disconnect(client, error) if client.room
server.end()
server.on 'close', (had_error) ->
log.info "server closed", client.name, had_error
server.closed = true unless server.closed
unless client.closed
sockets.splice(sockets.indexOf(client),1)
client.destroy()
client = null
server.end() if server
server.bye = () ->
unless !server || server.closed
server.closed = true
sockets.splice(sockets.indexOf(server),1)
server.destroy()
server = null
unless !client || client.closed
ygopro.stoc_send_chat(client, "服务器关闭了连接")
client.end()
client.end() if client
#释放处理
client.on 'close', () ->
#log.info "client closed", client.name
client.bye() if client
server.on 'error', (error)->
log.info "server error", client.name, error
server.closed = error
unless client.closed
ygopro.stoc_send_chat(client, "服务器错误: #{error}")
client.end()
client.on 'error', ()->
#log.info "client error", client.name
client.bye() if client
client.on 'end', ()->
#log.info "client end", client.name
client.bye() if client
client.on 'timeout', ()->
#log.info "client closed", client.name
client.bye() if client
server.on 'close', () ->
#log.info "server closed", client.name
server.bye() if server
server.on 'error', ()->
#log.info "server error", client.name
server.bye() if server
server.on 'end', ()->
#log.info "server end", client.name
server.bye() if server
server.on 'timeout', ()->
#log.info "server timeout", client.name
server.bye() if server
#需要重构
#客户端到服务端(ctos)协议分析
ctos_buffer = new Buffer(0)
ctos_message_length = 0
ctos_proto = 0
client.ctos_buffer = new Buffer(0)
client.ctos_message_length = 0
client.ctos_proto = 0
client.pre_establish_buffers = new Array()
client.on 'data', (data) ->
if client.is_post_watcher
if client.is_post_watcher and client.room.watcher
client.room.watcher.write data
else
ctos_buffer = Buffer.concat([ctos_buffer, data], ctos_buffer.length + data.length) #buffer的错误使用方式,好孩子不要学
client.ctos_buffer = Buffer.concat([client.ctos_buffer, data], client.ctos_buffer.length + data.length) #buffer的错误使用方式,好孩子不要学
if client.established
server.write data
server.write(data) if server
else
client.pre_establish_buffers.push data
while true
if ctos_message_length == 0
if ctos_buffer.length >= 2
ctos_message_length = ctos_buffer.readUInt16LE(0)
if client.ctos_message_length == 0
if client.ctos_buffer.length >= 2
client.ctos_message_length = client.ctos_buffer.readUInt16LE(0)
else
break
else if ctos_proto == 0
if ctos_buffer.length >= 3
ctos_proto = ctos_buffer.readUInt8(2)
else if client.ctos_proto == 0
if client.ctos_buffer.length >= 3
client.ctos_proto = client.ctos_buffer.readUInt8(2)
else
break
else
if ctos_buffer.length >= 2 + ctos_message_length
#console.log "CTOS", ygopro.constants.CTOS[ctos_proto]
if ygopro.ctos_follows[ctos_proto]
b = ctos_buffer.slice(3, ctos_message_length-1+3)
if struct = ygopro.structs[ygopro.proto_structs.CTOS[ygopro.constants.CTOS[ctos_proto]]]
if client.ctos_buffer.length >= 2 + client.ctos_message_length
#console.log "CTOS", ygopro.constants.CTOS[client.ctos_proto]
if ygopro.ctos_follows[client.ctos_proto]
b = client.ctos_buffer.slice(3, client.ctos_message_length-1+3)
if struct = ygopro.structs[ygopro.proto_structs.CTOS[ygopro.constants.CTOS[client.ctos_proto]]]
struct._setBuff(b)
ygopro.ctos_follows[ctos_proto].callback b, _.clone(struct.fields), client, server
ygopro.ctos_follows[client.ctos_proto].callback b, _.clone(struct.fields), client, server
else
ygopro.ctos_follows[ctos_proto].callback b, null, client, server
ygopro.ctos_follows[client.ctos_proto].callback b, null, client, server
ctos_buffer = ctos_buffer.slice(2 + ctos_message_length)
ctos_message_length = 0
ctos_proto = 0
client.ctos_buffer = client.ctos_buffer.slice(2 + client.ctos_message_length)
client.ctos_message_length = 0
client.ctos_proto = 0
else
break
#服务端到客户端(stoc)
stoc_buffer = new Buffer(0)
stoc_message_length = 0
stoc_proto = 0
server.stoc_buffer = new Buffer(0)
server.stoc_message_length = 0
server.stoc_proto = 0
server.on 'data', (data)->
stoc_buffer = Buffer.concat([stoc_buffer, data], stoc_buffer.length + data.length) #buffer的错误使用方式,好孩子不要学
server.stoc_buffer = Buffer.concat([server.stoc_buffer, data], server.stoc_buffer.length + data.length) #buffer的错误使用方式,好孩子不要学
#unless ygopro.stoc_follows[stoc_proto] and ygopro.stoc_follows[stoc_proto].synchronous
client.write data
#unless ygopro.stoc_follows[server.stoc_proto] and ygopro.stoc_follows[server.stoc_proto].synchronous
client.write data if client
while true
if stoc_message_length == 0
if stoc_buffer.length >= 2
stoc_message_length = stoc_buffer.readUInt16LE(0)
if server.stoc_message_length == 0
if server.stoc_buffer.length >= 2
server.stoc_message_length = server.stoc_buffer.readUInt16LE(0)
else
break
else if stoc_proto == 0
if stoc_buffer.length >= 3
stoc_proto = stoc_buffer.readUInt8(2)
else if server.stoc_proto == 0
if server.stoc_buffer.length >= 3
server.stoc_proto = server.stoc_buffer.readUInt8(2)
else
break
else
if stoc_buffer.length >= 2 + stoc_message_length
#console.log "STOC", ygopro.constants.STOC[stoc_proto]
stanzas = stoc_proto
if ygopro.stoc_follows[stoc_proto]
b = stoc_buffer.slice(3, stoc_message_length - 1 + 3)
if struct = ygopro.structs[ygopro.proto_structs.STOC[ygopro.constants.STOC[stoc_proto]]]
if server.stoc_buffer.length >= 2 + server.stoc_message_length
#console.log "STOC", ygopro.constants.STOC[server.stoc_proto]
stanzas = server.stoc_proto
if ygopro.stoc_follows[server.stoc_proto]
b = server.stoc_buffer.slice(3, server.stoc_message_length - 1 + 3)
if struct = ygopro.structs[ygopro.proto_structs.STOC[ygopro.constants.STOC[server.stoc_proto]]]
struct._setBuff(b)
ygopro.stoc_follows[stoc_proto].callback b, _.clone(struct.fields), client, server
ygopro.stoc_follows[server.stoc_proto].callback b, _.clone(struct.fields), client, server
else
ygopro.stoc_follows[stoc_proto].callback b, null, client, server
ygopro.stoc_follows[server.stoc_proto].callback b, null, client, server
stoc_buffer = stoc_buffer.slice(2 + stoc_message_length)
stoc_message_length = 0
stoc_proto = 0
server.stoc_buffer = server.stoc_buffer.slice(2 + server.stoc_message_length)
server.stoc_message_length = 0
server.stoc_proto = 0
else
break
......@@ -289,7 +318,7 @@ ygopro.stoc_follow 'GAME_MSG', false, (buffer, info, client, server)->
client.lp = client.room.hostinfo.start_lp
#ygopro.stoc_send_chat_to_room(client.room, "LP跟踪调试信息: #{client.name} 初始LP #{client.lp}")
if ygopro.constants.MSG[msg] == 'WIN' and _.startsWith(client.room.name, 'M#') and client.is_host
if client and ygopro.constants.MSG[msg] == 'WIN' and _.startsWith(client.room.name, 'M#') and client.is_host
pos = buffer.readUInt8(1)
pos = 1 - pos unless client.is_first or pos == 2
reason = buffer.readUInt8(2)
......@@ -368,7 +397,7 @@ if settings.modules.tips
#log.info "tips loaded", tips.length
ygopro.stoc_follow 'DUEL_START', false, (buffer, info, client, server)->
unless client.room.started #first start
if client && !client.room.started #first start
client.room.started = true
client.room.duels = []
client.room.dueling_players = []
......@@ -398,12 +427,12 @@ ygopro.ctos_follow 'CHAT', false, (buffer, info, client, server)->
else
#log.warn 'ping', stdout
ygopro.stoc_send_chat_to_room client.room, stdout
when '/count'
ygopro.stoc_send_chat(client,sockets.length.toString())
when '/help'
ygopro.stoc_send_chat(client,"YGOSrv233 指令帮助")
ygopro.stoc_send_chat(client,"/help 显示这个帮助信息")
ygopro.stoc_send_chat(client,"/tip 显示一条提示") if settings.modules.tips
#ygopro.stoc_send_chat(client,"/senddeck 发送自己的卡组")
when '/tip'
ygopro.stoc_send_random_tip(client) if settings.modules.tips
......
// Generated by CoffeeScript 1.9.3
(function() {
var Room, _, bunyan, debug, dialogues, execFile, fs, http, http_server, log, net, os, path, request, settings, tips, url, ygopro;
var Room, _, bunyan, debug, dialogues, execFile, fs, http, http_server, log, net, os, path, request, settings, sockets, tips, url, ygopro;
net = require('net');
......@@ -32,6 +32,8 @@
Room = require('./room.js');
sockets = [];
debug = false;
log = null;
......@@ -51,90 +53,125 @@
}
net.createServer(function(client) {
var ctos_buffer, ctos_message_length, ctos_proto, server, stoc_buffer, stoc_message_length, stoc_proto;
var server;
server = new net.Socket();
client.server = server;
client.on('close', function(had_error) {
log.info("client closed", client.name, had_error);
if (!client.closed) {
sockets.push(client);
sockets.push(server);
client.setTimeout(200000);
client.bye = function() {
if (!(!client || client.closed)) {
client.closed = true;
if (client.room) {
client.room.disconnect(client);
}
sockets.splice(sockets.indexOf(client), 1);
client.destroy();
client = null;
}
return server.end();
});
client.on('error', function(error) {
log.info("client error", client.name, error);
if (!client.closed) {
client.closed = error;
if (client.room) {
client.room.disconnect(client, error);
}
if (server) {
return server.end();
}
return server.end();
});
server.on('close', function(had_error) {
log.info("server closed", client.name, had_error);
if (!server.closed) {
};
server.bye = function() {
if (!(!server || server.closed)) {
server.closed = true;
sockets.splice(sockets.indexOf(server), 1);
server.destroy();
server = null;
}
if (!client.closed) {
if (!(!client || client.closed)) {
ygopro.stoc_send_chat(client, "服务器关闭了连接");
return client.end();
if (client) {
return client.end();
}
}
};
client.on('close', function() {
if (client) {
return client.bye();
}
});
client.on('error', function() {
if (client) {
return client.bye();
}
});
client.on('end', function() {
if (client) {
return client.bye();
}
});
client.on('timeout', function() {
if (client) {
return client.bye();
}
});
server.on('error', function(error) {
log.info("server error", client.name, error);
server.closed = error;
if (!client.closed) {
ygopro.stoc_send_chat(client, "服务器错误: " + error);
return client.end();
server.on('close', function() {
if (server) {
return server.bye();
}
});
ctos_buffer = new Buffer(0);
ctos_message_length = 0;
ctos_proto = 0;
server.on('error', function() {
if (server) {
return server.bye();
}
});
server.on('end', function() {
if (server) {
return server.bye();
}
});
server.on('timeout', function() {
if (server) {
return server.bye();
}
});
client.ctos_buffer = new Buffer(0);
client.ctos_message_length = 0;
client.ctos_proto = 0;
client.pre_establish_buffers = new Array();
client.on('data', function(data) {
var b, results, struct;
if (client.is_post_watcher) {
if (client.is_post_watcher && client.room.watcher) {
return client.room.watcher.write(data);
} else {
ctos_buffer = Buffer.concat([ctos_buffer, data], ctos_buffer.length + data.length);
client.ctos_buffer = Buffer.concat([client.ctos_buffer, data], client.ctos_buffer.length + data.length);
if (client.established) {
server.write(data);
if (server) {
server.write(data);
}
} else {
client.pre_establish_buffers.push(data);
}
results = [];
while (true) {
if (ctos_message_length === 0) {
if (ctos_buffer.length >= 2) {
results.push(ctos_message_length = ctos_buffer.readUInt16LE(0));
if (client.ctos_message_length === 0) {
if (client.ctos_buffer.length >= 2) {
results.push(client.ctos_message_length = client.ctos_buffer.readUInt16LE(0));
} else {
break;
}
} else if (ctos_proto === 0) {
if (ctos_buffer.length >= 3) {
results.push(ctos_proto = ctos_buffer.readUInt8(2));
} else if (client.ctos_proto === 0) {
if (client.ctos_buffer.length >= 3) {
results.push(client.ctos_proto = client.ctos_buffer.readUInt8(2));
} else {
break;
}
} else {
if (ctos_buffer.length >= 2 + ctos_message_length) {
if (ygopro.ctos_follows[ctos_proto]) {
b = ctos_buffer.slice(3, ctos_message_length - 1 + 3);
if (struct = ygopro.structs[ygopro.proto_structs.CTOS[ygopro.constants.CTOS[ctos_proto]]]) {
if (client.ctos_buffer.length >= 2 + client.ctos_message_length) {
if (ygopro.ctos_follows[client.ctos_proto]) {
b = client.ctos_buffer.slice(3, client.ctos_message_length - 1 + 3);
if (struct = ygopro.structs[ygopro.proto_structs.CTOS[ygopro.constants.CTOS[client.ctos_proto]]]) {
struct._setBuff(b);
ygopro.ctos_follows[ctos_proto].callback(b, _.clone(struct.fields), client, server);
ygopro.ctos_follows[client.ctos_proto].callback(b, _.clone(struct.fields), client, server);
} else {
ygopro.ctos_follows[ctos_proto].callback(b, null, client, server);
ygopro.ctos_follows[client.ctos_proto].callback(b, null, client, server);
}
}
ctos_buffer = ctos_buffer.slice(2 + ctos_message_length);
ctos_message_length = 0;
results.push(ctos_proto = 0);
client.ctos_buffer = client.ctos_buffer.slice(2 + client.ctos_message_length);
client.ctos_message_length = 0;
results.push(client.ctos_proto = 0);
} else {
break;
}
......@@ -143,42 +180,44 @@
return results;
}
});
stoc_buffer = new Buffer(0);
stoc_message_length = 0;
stoc_proto = 0;
server.stoc_buffer = new Buffer(0);
server.stoc_message_length = 0;
server.stoc_proto = 0;
return server.on('data', function(data) {
var b, results, stanzas, struct;
stoc_buffer = Buffer.concat([stoc_buffer, data], stoc_buffer.length + data.length);
client.write(data);
server.stoc_buffer = Buffer.concat([server.stoc_buffer, data], server.stoc_buffer.length + data.length);
if (client) {
client.write(data);
}
results = [];
while (true) {
if (stoc_message_length === 0) {
if (stoc_buffer.length >= 2) {
results.push(stoc_message_length = stoc_buffer.readUInt16LE(0));
if (server.stoc_message_length === 0) {
if (server.stoc_buffer.length >= 2) {
results.push(server.stoc_message_length = server.stoc_buffer.readUInt16LE(0));
} else {
break;
}
} else if (stoc_proto === 0) {
if (stoc_buffer.length >= 3) {
results.push(stoc_proto = stoc_buffer.readUInt8(2));
} else if (server.stoc_proto === 0) {
if (server.stoc_buffer.length >= 3) {
results.push(server.stoc_proto = server.stoc_buffer.readUInt8(2));
} else {
break;
}
} else {
if (stoc_buffer.length >= 2 + stoc_message_length) {
stanzas = stoc_proto;
if (ygopro.stoc_follows[stoc_proto]) {
b = stoc_buffer.slice(3, stoc_message_length - 1 + 3);
if (struct = ygopro.structs[ygopro.proto_structs.STOC[ygopro.constants.STOC[stoc_proto]]]) {
if (server.stoc_buffer.length >= 2 + server.stoc_message_length) {
stanzas = server.stoc_proto;
if (ygopro.stoc_follows[server.stoc_proto]) {
b = server.stoc_buffer.slice(3, server.stoc_message_length - 1 + 3);
if (struct = ygopro.structs[ygopro.proto_structs.STOC[ygopro.constants.STOC[server.stoc_proto]]]) {
struct._setBuff(b);
ygopro.stoc_follows[stoc_proto].callback(b, _.clone(struct.fields), client, server);
ygopro.stoc_follows[server.stoc_proto].callback(b, _.clone(struct.fields), client, server);
} else {
ygopro.stoc_follows[stoc_proto].callback(b, null, client, server);
ygopro.stoc_follows[server.stoc_proto].callback(b, null, client, server);
}
}
stoc_buffer = stoc_buffer.slice(2 + stoc_message_length);
stoc_message_length = 0;
results.push(stoc_proto = 0);
server.stoc_buffer = server.stoc_buffer.slice(2 + server.stoc_message_length);
server.stoc_message_length = 0;
results.push(server.stoc_proto = 0);
} else {
break;
}
......@@ -325,7 +364,7 @@
client.is_first = !(playertype & 0xf);
client.lp = client.room.hostinfo.start_lp;
}
if (ygopro.constants.MSG[msg] === 'WIN' && _.startsWith(client.room.name, 'M#') && client.is_host) {
if (client && ygopro.constants.MSG[msg] === 'WIN' && _.startsWith(client.room.name, 'M#') && client.is_host) {
pos = buffer.readUInt8(1);
if (!(client.is_first || pos === 2)) {
pos = 1 - pos;
......@@ -417,7 +456,7 @@
ygopro.stoc_follow('DUEL_START', false, function(buffer, info, client, server) {
var j, len, player, ref;
if (!client.room.started) {
if (client && !client.room.started) {
client.room.started = true;
client.room.duels = [];
client.room.dueling_players = [];
......@@ -450,6 +489,8 @@
}
}
});
case '/count':
return ygopro.stoc_send_chat(client, sockets.length.toString());
case '/help':
ygopro.stoc_send_chat(client, "YGOSrv233 指令帮助");
ygopro.stoc_send_chat(client, "/help 显示这个帮助信息");
......
......@@ -76,8 +76,9 @@ for name, declaration of structs_declaration
header = new Buffer(3)
header.writeUInt16LE buffer.length + 1, 0
header.writeUInt8 proto, 2
socket.write header
socket.write buffer if buffer.length
if socket
socket.write header
socket.write buffer if buffer.length
@ctos_send = (socket, proto, info)->
#console.log proto, proto_structs.CTOS[proto], structs[proto_structs.CTOS[proto]]
......@@ -101,8 +102,9 @@ for name, declaration of structs_declaration
header = new Buffer(3)
header.writeUInt16LE buffer.length + 1, 0
header.writeUInt8 proto, 2
socket.write header
socket.write buffer if buffer.length
if socket
socket.write header
socket.write buffer if buffer.length
#util
@stoc_send_chat = (client, msg, player = 8)->
......
......@@ -126,9 +126,11 @@
header = new Buffer(3);
header.writeUInt16LE(buffer.length + 1, 0);
header.writeUInt8(proto, 2);
socket.write(header);
if (buffer.length) {
return socket.write(buffer);
if (socket) {
socket.write(header);
if (buffer.length) {
return socket.write(buffer);
}
}
};
......@@ -160,9 +162,11 @@
header = new Buffer(3);
header.writeUInt16LE(buffer.length + 1, 0);
header.writeUInt8(proto, 2);
socket.write(header);
if (buffer.length) {
return socket.write(buffer);
if (socket) {
socket.write(header);
if (buffer.length) {
return socket.write(buffer);
}
}
};
......
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