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

fix

parent c3031484
......@@ -16,7 +16,8 @@
"moment": "latest",
"sqlite3": "latest",
"bunyan": "latest",
"ws": "latest"
"ws": "latest",
"pg": "latest"
},
"license": "AGPL-3.0",
"scripts": {
......
......@@ -383,7 +383,7 @@ class Room
Room.players_oppentlist[client.remoteAddress] = null
if @established
roomlist.update(this) unless @started
roomlist.update(this) if !@private and !@started
client.server.connect @port, '127.0.0.1', ->
client.server.write buffer for buffer in client.pre_establish_buffers
client.established = true
......@@ -405,7 +405,7 @@ class Room
Room.ban_player(client.name, client.ip, "强退")
if @players.length
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
else
@process.kill()
......
......@@ -496,7 +496,7 @@
}
}
if (this.established) {
if (!this.started) {
if (!this["private"] && !this.started) {
roomlist.update(this);
}
client.server.connect(this.port, '127.0.0.1', function() {
......@@ -530,7 +530,7 @@
}
if (this.players.length) {
ygopro.stoc_send_chat_to_room(this, client.name + " " + '离开了游戏' + (error ? ": " + error : ''));
if (!this.started) {
if (!this["private"] && !this.started) {
roomlist.update(this);
}
} else {
......
......@@ -36,6 +36,8 @@ ygopro = require './ygopro.js'
Room = require './room.js'
roomlist = require './roomlist.js'
users_cache = {}
#debug模式 端口号+1
debug = false
log = null
......@@ -320,41 +322,111 @@ ygopro.ctos_follow 'JOIN_GAME', false, (buffer, info, client, server)->
else if info.pass.length and settings.modules.mycard_auth
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
ygopro.stoc_send_chat(client,'主机密码不正确 (Invalid Length)', 11)
ygopro.stoc_send client, 'ERROR_MSG',{
msg: 1
code: 2
}
client.end()
return
if info.pass.length <= 8
ygopro.stoc_send_chat(client,'主机密码不正确 (Invalid Length)', 11)
ygopro.stoc_send client, 'ERROR_MSG',{
msg: 1
code: 2
}
client.end()
return
buffer = new Buffer(info.pass[0...8], 'base64')
check = (buf)->
checksum = 0
for i in [0...buf.length]
checksum += buf.readUInt8(i)
(checksum & 0xFF) == 0
finish = (buffer)->
action = buffer.readUInt8(1) >> 4
if buffer != decrypted_buffer and action in [1,2,4]
ygopro.stoc_send_chat(client,'主机密码不正确 (Unauthorized)', 11)
ygopro.stoc_send client, 'ERROR_MSG',{
msg: 1
code: 2
}
client.end()
return
buffer = new Buffer(info.pass[0...8], 'base64')
# 1 create public room
# 2 create private room
# 3 join room
# 4 join match
switch action
when 1,2
name = crypto.createHash('md5').update(info.pass + client.name).digest('base64')[0...10].replace('+','-').replace('/', '_');
if Room.find_by_name(name)
ygopro.stoc_send_chat(client,'主机密码不正确 (Already Existed)', 11)
ygopro.stoc_send client, 'ERROR_MSG',{
msg: 1
code: 2
}
client.end()
return
if buffer.length != 6
ygopro.stoc_send_chat(client,'主机密码不正确 (Invalid Payload Length)', 11)
opt1 = buffer.readUInt8(2)
opt2 = buffer.readUInt16LE(3)
opt3 = buffer.readUInt8(5)
options = {
lflist: 0
time_limit: 180
rule: (opt1 >> 5) & 3
mode: (opt1 >> 3) & 3
enable_priority: !!((opt1 >> 2) & 1)
no_check_deck: !!((opt1 >> 1) & 1)
no_shuffle_deck: !!(opt1 & 1)
start_lp: opt2
start_hand: opt3 >> 4
draw_count: opt3 & 0xF
}
room = new Room(name, options)
room.title = info.pass.slice(8).replace(String.fromCharCode(0xFEFF), ' ')
room.private = action == 2
when 3
name = info.pass.slice(8)
room = Room.find_by_name(name)
if(!room)
ygopro.stoc_send_chat(client,'主机密码不正确 (Not Found)', 11)
ygopro.stoc_send client, 'ERROR_MSG',{
msg: 1
code: 2
}
client.end()
return
when 4
room = Room.find_or_create_by_name('M#' + info.pass.slice(8))
room.private = true
else
ygopro.stoc_send_chat(client,'主机密码不正确 (Invalid Action)', 11)
ygopro.stoc_send client, 'ERROR_MSG',{
msg: 1
code: 2
}
client.end()
return
client.room = room
client.room.connect(client)
check = (buf)->
checksum = 0
for i in [0...buf.length]
checksum += buf.readUInt8(i)
(checksum & 0xFF) == 0
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)
......@@ -373,76 +445,8 @@ ygopro.ctos_follow 'JOIN_GAME', false, (buffer, info, client, server)->
}
client.end()
return
action = buffer.readUInt8(1) >> 4
if buffer != decrypted_buffer and action in [1,2,4]
ygopro.stoc_send_chat(client,'主机密码不正确 (Unauthorized)', 11)
ygopro.stoc_send client, 'ERROR_MSG',{
msg: 1
code: 2
}
client.end()
return
# 1 create public room
# 2 create private room
# 3 join room
# 4 join match
switch action
when 1,2
name = crypto.createHash('md5').update(info.pass + client.name).digest('base64')[0...10].replace('+','-').replace('/', '_');
if Room.find_by_name(name)
ygopro.stoc_send_chat(client,'主机密码不正确 (Already Existed)', 11)
ygopro.stoc_send client, 'ERROR_MSG',{
msg: 1
code: 2
}
client.end()
return
opt1 = buffer.readUInt8(2)
opt2 = buffer.readUInt16LE(3)
opt3 = buffer.readUInt8(5)
options = {
lflist: 0
time_limit: 180
rule: (opt1 >> 5) & 3
mode: (opt1 >> 3) & 3
enable_priority: !!((opt1 >> 2) & 1)
no_check_deck: !!((opt1 >> 1) & 1)
no_shuffle_deck: !!(opt1 & 1)
start_lp: opt2
start_hand: opt3 >> 4
draw_count: opt3 & 0xF
}
room = new Room(name, options)
room.title = info.pass.slice(8).replace(String.fromCharCode(0xFEFF), ' ')
room.private = action == 2
when 3
name = info.pass.slice(8)
room = Room.find_by_name(name)
if(!room)
ygopro.stoc_send_chat(client,'主机密码不正确 (Not Found)', 11)
ygopro.stoc_send client, 'ERROR_MSG',{
msg: 1
code: 2
}
client.end()
return
when 4
room = Room.find_or_create_by_name('M#' + info.pass.slice(8))
room.private = true
else
ygopro.stoc_send_chat(client,'主机密码不正确 (Invalid Action)', 11)
ygopro.stoc_send client, 'ERROR_MSG',{
msg: 1
code: 2
}
client.end()
return
client.room = room
client.room.connect(client)
users_cache[client.name] = body.user.id
finish(buffer)
else if info.pass.length && !Room.validate(info.pass)
#ygopro.stoc_send client, 'ERROR_MSG',{
......@@ -630,7 +634,6 @@ ygopro.stoc_follow 'GAME_MSG', false, (buffer, info, client, server)->
if dialogues[card]
for line in _.lines dialogues[card][Math.floor(Math.random() * dialogues[card].length)]
ygopro.stoc_send_chat client, line, 15
return
#房间管理
ygopro.ctos_follow 'HS_KICK', true, (buffer, info, client, server)->
......@@ -703,6 +706,17 @@ if settings.modules.tips
#log.info "tips loaded", tips.length
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)->
return unless client.room
unless client.room.started #first start
......@@ -881,4 +895,4 @@ if settings.modules.http
key: fs.readFileSync(settings.modules.http.ssl.key)
https_server = https.createServer(options, requestListener)
roomlist.init https_server, Room
https_server.listen settings.modules.http.ssl.port
https_server.listen settings.modules.http.ssl.port
\ No newline at end of file
// Generated by CoffeeScript 1.9.3
(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');
......@@ -46,6 +46,8 @@
roomlist = require('./roomlist.js');
users_cache = {};
debug = false;
log = null;
......@@ -289,7 +291,7 @@
});
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) {
ygopro.stoc_send_chat(client, settings.modules.stop, 11);
ygopro.stoc_send(client, 'ERROR_MSG', {
......@@ -348,65 +350,26 @@
client.end();
} else if (info.pass.length && settings.modules.mycard_auth) {
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) {
ygopro.stoc_send_chat(client, '主机密码不正确 (Invalid Length)', 11);
ygopro.stoc_send(client, 'ERROR_MSG', {
msg: 1,
code: 2
});
client.end();
return;
}
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) {
var checksum, i, k, ref;
checksum = 0;
for (i = k = 0, ref = buf.length; 0 <= ref ? k < ref : k > ref; i = 0 <= ref ? ++k : --k) {
checksum += buf.readUInt8(i);
}
return (checksum & 0xFF) === 0;
};
if (body && body.user) {
secret = body.user.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)) {
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;
if (info.pass.length <= 8) {
ygopro.stoc_send_chat(client, '主机密码不正确 (Invalid Length)', 11);
ygopro.stoc_send(client, 'ERROR_MSG', {
msg: 1,
code: 2
});
client.end();
return;
}
buffer = new Buffer(info.pass.slice(0, 8), 'base64');
check = function(buf) {
var checksum, i, k, ref;
checksum = 0;
for (i = k = 0, ref = buf.length; 0 <= ref ? k < ref : k > ref; i = 0 <= ref ? ++k : --k) {
checksum += buf.readUInt8(i);
}
return (checksum & 0xFF) === 0;
};
finish = function(buffer) {
var action, name, opt1, opt2, opt3, options, room;
action = buffer.readUInt8(1) >> 4;
if (buffer !== decrypted_buffer && (action === 1 || action === 2 || action === 4)) {
ygopro.stoc_send_chat(client, '主机密码不正确 (Unauthorized)', 11);
......@@ -477,6 +440,53 @@
}
client.room = room;
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)) {
ygopro.stoc_send_chat(client, "房间密码不正确", 11);
......@@ -531,9 +541,9 @@
ygopro.stoc_send_chat_to_room(client.room, client.name + " 加入了观战");
client.room.watchers.push(client);
ygopro.stoc_send_chat(client, "观战中", 14);
ref = client.room.watcher_buffers;
for (k = 0, len = ref.length; k < len; k++) {
buffer = ref[k];
ref1 = client.room.watcher_buffers;
for (l = 0, len1 = ref1.length; l < len1; l++) {
buffer = ref1[l];
client.write(buffer);
}
} else {
......@@ -610,7 +620,7 @@
}
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);
if (msg >= 10 && msg < 30) {
client.room.waiting_for_player = client;
......@@ -673,10 +683,12 @@
card = buffer.readUInt32LE(1);
if (dialogues[card]) {
ref2 = _.lines(dialogues[card][Math.floor(Math.random() * dialogues[card].length)]);
results = [];
for (k = 0, len = ref2.length; k < len; 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 @@
});
}
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) {
var k, len, player, ref;
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