Commit c16fe70d authored by 神楽坂玲奈's avatar 神楽坂玲奈 Committed by Ma

fix

parent c3031484
...@@ -16,7 +16,8 @@ ...@@ -16,7 +16,8 @@
"moment": "latest", "moment": "latest",
"sqlite3": "latest", "sqlite3": "latest",
"bunyan": "latest", "bunyan": "latest",
"ws": "latest" "ws": "latest",
"pg": "latest"
}, },
"license": "AGPL-3.0", "license": "AGPL-3.0",
"scripts": { "scripts": {
......
...@@ -383,7 +383,7 @@ class Room ...@@ -383,7 +383,7 @@ class Room
Room.players_oppentlist[client.remoteAddress] = null Room.players_oppentlist[client.remoteAddress] = null
if @established if @established
roomlist.update(this) unless @started roomlist.update(this) if !@private and !@started
client.server.connect @port, '127.0.0.1', -> client.server.connect @port, '127.0.0.1', ->
client.server.write buffer for buffer in client.pre_establish_buffers client.server.write buffer for buffer in client.pre_establish_buffers
client.established = true client.established = true
...@@ -405,7 +405,7 @@ class Room ...@@ -405,7 +405,7 @@ class Room
Room.ban_player(client.name, client.ip, "强退") Room.ban_player(client.name, client.ip, "强退")
if @players.length if @players.length
ygopro.stoc_send_chat_to_room this, "#{client.name} #{'离开了游戏'}#{if error then ": #{error}" else ''}" ygopro.stoc_send_chat_to_room this, "#{client.name} #{'离开了游戏'}#{if error then ": #{error}" else ''}"
roomlist.update(this) unless @started roomlist.update(this) if !@private and !@started
#client.room = null #client.room = null
else else
@process.kill() @process.kill()
......
...@@ -496,7 +496,7 @@ ...@@ -496,7 +496,7 @@
} }
} }
if (this.established) { if (this.established) {
if (!this.started) { if (!this["private"] && !this.started) {
roomlist.update(this); roomlist.update(this);
} }
client.server.connect(this.port, '127.0.0.1', function() { client.server.connect(this.port, '127.0.0.1', function() {
...@@ -530,7 +530,7 @@ ...@@ -530,7 +530,7 @@
} }
if (this.players.length) { if (this.players.length) {
ygopro.stoc_send_chat_to_room(this, client.name + " " + '离开了游戏' + (error ? ": " + error : '')); ygopro.stoc_send_chat_to_room(this, client.name + " " + '离开了游戏' + (error ? ": " + error : ''));
if (!this.started) { if (!this["private"] && !this.started) {
roomlist.update(this); roomlist.update(this);
} }
} else { } else {
......
...@@ -36,6 +36,8 @@ ygopro = require './ygopro.js' ...@@ -36,6 +36,8 @@ ygopro = require './ygopro.js'
Room = require './room.js' Room = require './room.js'
roomlist = require './roomlist.js' roomlist = require './roomlist.js'
users_cache = {}
#debug模式 端口号+1 #debug模式 端口号+1
debug = false debug = false
log = null log = null
...@@ -320,15 +322,6 @@ ygopro.ctos_follow 'JOIN_GAME', false, (buffer, info, client, server)-> ...@@ -320,15 +322,6 @@ ygopro.ctos_follow 'JOIN_GAME', false, (buffer, info, client, server)->
else if info.pass.length and settings.modules.mycard_auth else if info.pass.length and settings.modules.mycard_auth
ygopro.stoc_send_chat(client,'正在读取用户信息...', 11) ygopro.stoc_send_chat(client,'正在读取用户信息...', 11)
request
baseUrl: settings.modules.mycard_auth,
url: '/users/' + encodeURIComponent(client.name) + '.json'
qs:
api_key: 'dc7298a754828b3d26b709f035a0eeceb43e73cbd8c4fa8dec18951f8a95d2bc',
api_username: client.name,
skip_track_visit: true
json: true
, (error, response, body)->
if info.pass.length <= 8 if info.pass.length <= 8
ygopro.stoc_send_chat(client,'主机密码不正确 (Invalid Length)', 11) ygopro.stoc_send_chat(client,'主机密码不正确 (Invalid Length)', 11)
ygopro.stoc_send client, 'ERROR_MSG',{ ygopro.stoc_send client, 'ERROR_MSG',{
...@@ -340,41 +333,13 @@ ygopro.ctos_follow 'JOIN_GAME', false, (buffer, info, client, server)-> ...@@ -340,41 +333,13 @@ ygopro.ctos_follow 'JOIN_GAME', false, (buffer, info, client, server)->
buffer = new Buffer(info.pass[0...8], 'base64') buffer = new Buffer(info.pass[0...8], 'base64')
if buffer.length != 6
ygopro.stoc_send_chat(client,'主机密码不正确 (Invalid Payload Length)', 11)
ygopro.stoc_send client, 'ERROR_MSG',{
msg: 1
code: 2
}
client.end()
return
check = (buf)-> check = (buf)->
checksum = 0 checksum = 0
for i in [0...buf.length] for i in [0...buf.length]
checksum += buf.readUInt8(i) checksum += buf.readUInt8(i)
(checksum & 0xFF) == 0 (checksum & 0xFF) == 0
if body and body.user finish = (buffer)->
secret = body.user.id % 65535 + 1;
decrypted_buffer = new Buffer(6)
for i in [0,2,4]
decrypted_buffer.writeUInt16LE(buffer.readUInt16LE(i) ^ secret, i)
if check(decrypted_buffer)
buffer = decrypted_buffer
# buffer != decrypted_buffer ==> auth failed
if !check(buffer)
ygopro.stoc_send_chat(client,'主机密码不正确 (Checksum Failed)', 11)
ygopro.stoc_send client, 'ERROR_MSG',{
msg: 1
code: 2
}
client.end()
return
action = buffer.readUInt8(1) >> 4 action = buffer.readUInt8(1) >> 4
if buffer != decrypted_buffer and action in [1,2,4] if buffer != decrypted_buffer and action in [1,2,4]
ygopro.stoc_send_chat(client,'主机密码不正确 (Unauthorized)', 11) ygopro.stoc_send_chat(client,'主机密码不正确 (Unauthorized)', 11)
...@@ -444,6 +409,45 @@ ygopro.ctos_follow 'JOIN_GAME', false, (buffer, info, client, server)-> ...@@ -444,6 +409,45 @@ ygopro.ctos_follow 'JOIN_GAME', false, (buffer, info, client, server)->
client.room = room client.room = room
client.room.connect(client) client.room.connect(client)
if id = users_cache[client.name]
secret = id % 65535 + 1;
decrypted_buffer = new Buffer(6)
for i in [0,2,4]
decrypted_buffer.writeUInt16LE(buffer.readUInt16LE(i) ^ secret, i)
if check(decrypted_buffer)
return finish(decrypted_buffer)
#TODO: query database directly, like preload.
request
baseUrl: settings.modules.mycard_auth,
url: '/users/' + encodeURIComponent(client.name) + '.json',
qs:
api_key: 'dc7298a754828b3d26b709f035a0eeceb43e73cbd8c4fa8dec18951f8a95d2bc',
api_username: client.name,
skip_track_visit: true
json: true
, (error, response, body)->
if body and body.user
secret = body.user.id % 65535 + 1;
decrypted_buffer = new Buffer(6)
for i in [0,2,4]
decrypted_buffer.writeUInt16LE(buffer.readUInt16LE(i) ^ secret, i)
if check(decrypted_buffer)
buffer = decrypted_buffer
# buffer != decrypted_buffer ==> auth failed
if !check(buffer)
ygopro.stoc_send_chat(client,'主机密码不正确 (Checksum Failed)', 11)
ygopro.stoc_send client, 'ERROR_MSG',{
msg: 1
code: 2
}
client.end()
return
users_cache[client.name] = body.user.id
finish(buffer)
else if info.pass.length && !Room.validate(info.pass) else if info.pass.length && !Room.validate(info.pass)
#ygopro.stoc_send client, 'ERROR_MSG',{ #ygopro.stoc_send client, 'ERROR_MSG',{
# msg: 1 # msg: 1
...@@ -630,7 +634,6 @@ ygopro.stoc_follow 'GAME_MSG', false, (buffer, info, client, server)-> ...@@ -630,7 +634,6 @@ ygopro.stoc_follow 'GAME_MSG', false, (buffer, info, client, server)->
if dialogues[card] if dialogues[card]
for line in _.lines dialogues[card][Math.floor(Math.random() * dialogues[card].length)] for line in _.lines dialogues[card][Math.floor(Math.random() * dialogues[card].length)]
ygopro.stoc_send_chat client, line, 15 ygopro.stoc_send_chat client, line, 15
return
#房间管理 #房间管理
ygopro.ctos_follow 'HS_KICK', true, (buffer, info, client, server)-> ygopro.ctos_follow 'HS_KICK', true, (buffer, info, client, server)->
...@@ -703,6 +706,17 @@ if settings.modules.tips ...@@ -703,6 +706,17 @@ if settings.modules.tips
#log.info "tips loaded", tips.length #log.info "tips loaded", tips.length
return return
if settings.modules.mycard_auth and process.env.MYCARD_AUTH_DATABASE
pg = require('pg');
pg.connect process.env.MYCARD_AUTH_DATABASE, (error, client, done)->
if(error)
return console.error('error fetching client from pool', err);
client.query 'SELECT username, id from users', (error, result)->
done();
for row in result.rows
users_cache[row.username] = row.id
console.log("users loaded", _.keys(users_cache).length)
ygopro.stoc_follow 'DUEL_START', false, (buffer, info, client, server)-> ygopro.stoc_follow 'DUEL_START', false, (buffer, info, client, server)->
return unless client.room return unless client.room
unless client.room.started #first start unless client.room.started #first start
......
// Generated by CoffeeScript 1.9.3 // Generated by CoffeeScript 1.9.3
(function() { (function() {
var Graveyard, Room, _, bunyan, crypto, debug, dialogues, execFile, fs, http, http_server, https, https_server, log, moment, net, options, os, path, request, requestListener, roomlist, settings, tips, tribute, url, wait_room_start, ygopro; var Graveyard, Room, _, bunyan, crypto, debug, dialogues, execFile, fs, http, http_server, https, https_server, log, moment, net, options, os, path, pg, request, requestListener, roomlist, settings, tips, tribute, url, users_cache, wait_room_start, ygopro;
net = require('net'); net = require('net');
...@@ -46,6 +46,8 @@ ...@@ -46,6 +46,8 @@
roomlist = require('./roomlist.js'); roomlist = require('./roomlist.js');
users_cache = {};
debug = false; debug = false;
log = null; log = null;
...@@ -289,7 +291,7 @@ ...@@ -289,7 +291,7 @@
}); });
ygopro.ctos_follow('JOIN_GAME', false, function(buffer, info, client, server) { ygopro.ctos_follow('JOIN_GAME', false, function(buffer, info, client, server) {
var k, len, ref, room; var check, decrypted_buffer, finish, i, id, k, l, len, len1, ref, ref1, room, secret;
if (settings.modules.stop) { if (settings.modules.stop) {
ygopro.stoc_send_chat(client, settings.modules.stop, 11); ygopro.stoc_send_chat(client, settings.modules.stop, 11);
ygopro.stoc_send(client, 'ERROR_MSG', { ygopro.stoc_send(client, 'ERROR_MSG', {
...@@ -348,17 +350,6 @@ ...@@ -348,17 +350,6 @@
client.end(); client.end();
} else if (info.pass.length && settings.modules.mycard_auth) { } else if (info.pass.length && settings.modules.mycard_auth) {
ygopro.stoc_send_chat(client, '正在读取用户信息...', 11); ygopro.stoc_send_chat(client, '正在读取用户信息...', 11);
request({
baseUrl: settings.modules.mycard_auth,
url: '/users/' + encodeURIComponent(client.name) + '.json',
qs: {
api_key: 'dc7298a754828b3d26b709f035a0eeceb43e73cbd8c4fa8dec18951f8a95d2bc',
api_username: client.name,
skip_track_visit: true
},
json: true
}, function(error, response, body) {
var action, check, decrypted_buffer, i, k, len, name, opt1, opt2, opt3, options, ref, room, secret;
if (info.pass.length <= 8) { if (info.pass.length <= 8) {
ygopro.stoc_send_chat(client, '主机密码不正确 (Invalid Length)', 11); ygopro.stoc_send_chat(client, '主机密码不正确 (Invalid Length)', 11);
ygopro.stoc_send(client, 'ERROR_MSG', { ygopro.stoc_send(client, 'ERROR_MSG', {
...@@ -369,15 +360,6 @@ ...@@ -369,15 +360,6 @@
return; return;
} }
buffer = new Buffer(info.pass.slice(0, 8), 'base64'); buffer = new Buffer(info.pass.slice(0, 8), 'base64');
if (buffer.length !== 6) {
ygopro.stoc_send_chat(client, '主机密码不正确 (Invalid Payload Length)', 11);
ygopro.stoc_send(client, 'ERROR_MSG', {
msg: 1,
code: 2
});
client.end();
return;
}
check = function(buf) { check = function(buf) {
var checksum, i, k, ref; var checksum, i, k, ref;
checksum = 0; checksum = 0;
...@@ -386,27 +368,8 @@ ...@@ -386,27 +368,8 @@
} }
return (checksum & 0xFF) === 0; return (checksum & 0xFF) === 0;
}; };
if (body && body.user) { finish = function(buffer) {
secret = body.user.id % 65535 + 1; var action, name, opt1, opt2, opt3, options, room;
decrypted_buffer = new Buffer(6);
ref = [0, 2, 4];
for (k = 0, len = ref.length; k < len; k++) {
i = ref[k];
decrypted_buffer.writeUInt16LE(buffer.readUInt16LE(i) ^ secret, i);
}
if (check(decrypted_buffer)) {
buffer = decrypted_buffer;
}
}
if (!check(buffer)) {
ygopro.stoc_send_chat(client, '主机密码不正确 (Checksum Failed)', 11);
ygopro.stoc_send(client, 'ERROR_MSG', {
msg: 1,
code: 2
});
client.end();
return;
}
action = buffer.readUInt8(1) >> 4; action = buffer.readUInt8(1) >> 4;
if (buffer !== decrypted_buffer && (action === 1 || action === 2 || action === 4)) { if (buffer !== decrypted_buffer && (action === 1 || action === 2 || action === 4)) {
ygopro.stoc_send_chat(client, '主机密码不正确 (Unauthorized)', 11); ygopro.stoc_send_chat(client, '主机密码不正确 (Unauthorized)', 11);
...@@ -477,6 +440,53 @@ ...@@ -477,6 +440,53 @@
} }
client.room = room; client.room = room;
return client.room.connect(client); return client.room.connect(client);
};
if (id = users_cache[client.name]) {
secret = id % 65535 + 1;
decrypted_buffer = new Buffer(6);
ref = [0, 2, 4];
for (k = 0, len = ref.length; k < len; k++) {
i = ref[k];
decrypted_buffer.writeUInt16LE(buffer.readUInt16LE(i) ^ secret, i);
}
if (check(decrypted_buffer)) {
return finish(decrypted_buffer);
}
}
request({
baseUrl: settings.modules.mycard_auth,
url: '/users/' + encodeURIComponent(client.name) + '.json',
qs: {
api_key: 'dc7298a754828b3d26b709f035a0eeceb43e73cbd8c4fa8dec18951f8a95d2bc',
api_username: client.name,
skip_track_visit: true
},
json: true
}, function(error, response, body) {
var l, len1, ref1;
if (body && body.user) {
secret = body.user.id % 65535 + 1;
decrypted_buffer = new Buffer(6);
ref1 = [0, 2, 4];
for (l = 0, len1 = ref1.length; l < len1; l++) {
i = ref1[l];
decrypted_buffer.writeUInt16LE(buffer.readUInt16LE(i) ^ secret, i);
}
if (check(decrypted_buffer)) {
buffer = decrypted_buffer;
}
}
if (!check(buffer)) {
ygopro.stoc_send_chat(client, '主机密码不正确 (Checksum Failed)', 11);
ygopro.stoc_send(client, 'ERROR_MSG', {
msg: 1,
code: 2
});
client.end();
return;
}
users_cache[client.name] = body.user.id;
return finish(buffer);
}); });
} else if (info.pass.length && !Room.validate(info.pass)) { } else if (info.pass.length && !Room.validate(info.pass)) {
ygopro.stoc_send_chat(client, "房间密码不正确", 11); ygopro.stoc_send_chat(client, "房间密码不正确", 11);
...@@ -531,9 +541,9 @@ ...@@ -531,9 +541,9 @@
ygopro.stoc_send_chat_to_room(client.room, client.name + " 加入了观战"); ygopro.stoc_send_chat_to_room(client.room, client.name + " 加入了观战");
client.room.watchers.push(client); client.room.watchers.push(client);
ygopro.stoc_send_chat(client, "观战中", 14); ygopro.stoc_send_chat(client, "观战中", 14);
ref = client.room.watcher_buffers; ref1 = client.room.watcher_buffers;
for (k = 0, len = ref.length; k < len; k++) { for (l = 0, len1 = ref1.length; l < len1; l++) {
buffer = ref[k]; buffer = ref1[l];
client.write(buffer); client.write(buffer);
} }
} else { } else {
...@@ -610,7 +620,7 @@ ...@@ -610,7 +620,7 @@
} }
ygopro.stoc_follow('GAME_MSG', false, function(buffer, info, client, server) { ygopro.stoc_follow('GAME_MSG', false, function(buffer, info, client, server) {
var card, k, len, line, msg, playertype, pos, ref, ref1, ref2, val; var card, k, len, line, msg, playertype, pos, ref, ref1, ref2, results, val;
msg = buffer.readInt8(0); msg = buffer.readInt8(0);
if (msg >= 10 && msg < 30) { if (msg >= 10 && msg < 30) {
client.room.waiting_for_player = client; client.room.waiting_for_player = client;
...@@ -673,10 +683,12 @@ ...@@ -673,10 +683,12 @@
card = buffer.readUInt32LE(1); card = buffer.readUInt32LE(1);
if (dialogues[card]) { if (dialogues[card]) {
ref2 = _.lines(dialogues[card][Math.floor(Math.random() * dialogues[card].length)]); ref2 = _.lines(dialogues[card][Math.floor(Math.random() * dialogues[card].length)]);
results = [];
for (k = 0, len = ref2.length; k < len; k++) { for (k = 0, len = ref2.length; k < len; k++) {
line = ref2[k]; line = ref2[k];
ygopro.stoc_send_chat(client, line, 15); results.push(ygopro.stoc_send_chat(client, line, 15));
} }
return results;
} }
} }
} }
...@@ -791,6 +803,25 @@ ...@@ -791,6 +803,25 @@
}); });
} }
if (settings.modules.mycard_auth && process.env.MYCARD_AUTH_DATABASE) {
pg = require('pg');
pg.connect(process.env.MYCARD_AUTH_DATABASE, function(error, client, done) {
if (error) {
return console.error('error fetching client from pool', err);
}
return client.query('SELECT username, id from users', function(error, result) {
var k, len, ref, row;
done();
ref = result.rows;
for (k = 0, len = ref.length; k < len; k++) {
row = ref[k];
users_cache[row.username] = row.id;
}
return console.log("users loaded", _.keys(users_cache).length);
});
});
}
ygopro.stoc_follow('DUEL_START', false, function(buffer, info, client, server) { ygopro.stoc_follow('DUEL_START', false, function(buffer, info, client, server) {
var k, len, player, ref; var k, len, player, ref;
if (!client.room) { if (!client.room) {
......
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