Commit 58ca63d1 authored by 神楽坂玲奈's avatar 神楽坂玲奈

11.7

parent 59421bd9
{ {
"ip": "112.124.4.110", "ip": "112.124.4.110",
"port": 7911, "port": 7911,
"http_port": 7922, "version": 4896,
"version": 4896 "modules": {
"welcome": "Mycard MatchServer\n这里是测试中的新服务器, 还不稳定, 随时可能崩溃, 遇到意外请淡定",
"tips": "https://my-card.in/tips.json",
"dialogues": "https://my-card.in/dialogues.json",
"database": "mongodb://phoenix.my-card.in/mycard",
"post_start_watching": false,
"skip_empty_side": true,
"http": {
"port": 7922,
"match": true
}
}
} }
\ No newline at end of file
settings = require './config.json'
mongoose = require 'mongoose'
Deck = mongoose.model 'Deck',
name: String
card_usages: [{
card_id: Number,
side: Boolean,
count: Number
}],
user: mongoose.Schema.ObjectId
created_at: { type: Date, default: Date.now },
used_count: Number,
last_used_at: Date
module.exports = Deck
\ No newline at end of file
// Generated by CoffeeScript 1.6.3
(function() {
var Deck, mongoose, settings;
settings = require('./config.json');
mongoose = require('mongoose');
Deck = mongoose.model('Deck', {
name: String,
card_usages: [
{
card_id: Number,
side: Boolean,
count: Number
}
],
user: mongoose.Schema.ObjectId,
created_at: {
type: Date,
"default": Date.now
},
used_count: Number,
last_used_at: Date
});
module.exports = Deck;
}).call(this);
/*
//@ sourceMappingURL=deck.map
*/
{
"version": 3,
"file": "deck.js",
"sourceRoot": "",
"sources": [
"deck.coffee"
],
"names": [],
"mappings": ";AAAA;CAAA,KAAA,kBAAA;;CAAA,CAAA,CAAW,IAAA,CAAX,OAAW;;CAAX,CAEA,CAAW,IAAA,CAAX,EAAW;;CAFX,CAGA,CAAO,CAAP,CAAO,CAAA,EAAQ;CACb,CAAM,EAAN,EAAA;CAAA,CACa,EAAb,OAAA;OAAc;CAAA,CACH,IADG,CACZ,CAAA;CADY,CAEN,EAAN,GAFY,CAEZ;CAFY,CAGL,GAAP,CAHY,EAGZ;QAHW;MADb;CAAA,CAMM,EAAN,EAAqB,EAAP;CANd,CAOY,EAAZ,MAAA;CAAY,CAAQ,EAAN,EAAA;CAAF,CAAuB,CAAvB,CAA2B,EAAb,GAAA;MAP1B;CAAA,CAQY,EAAZ,EARA,IAQA;CARA,CASc,EAAd,QAAA;CAbF,GAGO;;CAHP,CAeA,CAAiB,CAfjB,EAeM,CAAN;CAfA"
}
\ No newline at end of file
[-10,20,50,100,180,300,450,650,1000,1400,2000,3000]
\ No newline at end of file
settings = require './config.json'
mongoose = require 'mongoose'
Match = mongoose.model 'Match',
players: [{
user: mongoose.Schema.ObjectId,
deck: mongoose.Schema.ObjectId,
}],
duels: [{
winner: Number
reason: Number
}],
winner: mongoose.Schema.ObjectId,
created_at: { type: Date, default: Date.now },
ygopro_version: Number
module.exports = Match
\ No newline at end of file
// Generated by CoffeeScript 1.6.3
(function() {
var Match, mongoose, settings;
settings = require('./config.json');
mongoose = require('mongoose');
Match = mongoose.model('Match', {
players: [
{
user: mongoose.Schema.ObjectId,
deck: mongoose.Schema.ObjectId
}
],
duels: [
{
winner: Number,
reason: Number
}
],
winner: mongoose.Schema.ObjectId,
created_at: {
type: Date,
"default": Date.now
},
ygopro_version: Number
});
module.exports = Match;
}).call(this);
/*
//@ sourceMappingURL=match.map
*/
{
"version": 3,
"file": "match.js",
"sourceRoot": "",
"sources": [
"match.coffee"
],
"names": [],
"mappings": ";AAAA;CAAA,KAAA,mBAAA;;CAAA,CAAA,CAAW,IAAA,CAAX,OAAW;;CAAX,CAEA,CAAW,IAAA,CAAX,EAAW;;CAFX,CAGA,CAAQ,EAAR,EAAQ,CAAQ;CACd,CAAS,EAAT,GAAA;OAAU;CAAA,CACF,EAAN,EAAqB,EAArB;CADQ,CAEF,EAAN,EAAqB,EAArB;QAFO;MAAT;CAAA,CAIO,EAAP,CAAA;OAAQ;CAAA,CACE,IAAR,EAAA;CADM,CAEE,IAAR,EAAA;QAFK;MAJP;CAAA,CAQQ,EAAR,EAAA,EAAgB;CARhB,CASY,EAAZ,MAAA;CAAY,CAAQ,EAAN,EAAA;CAAF,CAAuB,CAAvB,CAA2B,EAAb,GAAA;MAT1B;CAAA,CAUgB,EAAhB,EAVA,QAUA;CAdF,GAGQ;;CAHR,CAgBA,CAAiB,EAhBjB,CAgBM,CAAN;CAhBA"
}
\ No newline at end of file
request = require 'request'
@key = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_="
@load_card_usages_from_cards = (main, side)->
result = []
last_id = null
for card_id in main
if card_id == last_id
count++
else
result.push {card_id: last_id, side: false, count: count} if last_id
last_id = card_id
count = 1
result.push {card_id: last_id, side: false, count: count} if last_id
last_id = null
for card_id in side
if card_id == last_id
count++
else
result.push {card_id: last_id, side: true, count: count} if last_id
last_id = card_id
count = 1
result.push {card_id: last_id, side: true, count: count} if last_id
result
@encode = (card_usages)->
result = ''
for card_usage in card_usages
c = card_usage.side << 29 | card_usage.count << 27 | card_usage.card_id
for i in [4..0]
result += @key.charAt((c >> i * 6) & 0x3F)
result
@deck_url = (name, card_usages, format)->
"https://my-card.in/decks/new#{if format then '.' + format else ''}?name=#{encodeURIComponent name}&cards=#{@encode card_usages}"
@deck_url_short = (name, card_usages, callback)->
request = require 'request'
request @deck_url(name, card_usages, 'short.url'), (error, response, body)->
callback body
\ No newline at end of file
// Generated by CoffeeScript 1.6.3
(function() {
var request;
request = require('request');
this.key = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_=";
this.load_card_usages_from_cards = function(main, side) {
var card_id, count, last_id, result, _i, _j, _len, _len1;
result = [];
last_id = null;
for (_i = 0, _len = main.length; _i < _len; _i++) {
card_id = main[_i];
if (card_id === last_id) {
count++;
} else {
if (last_id) {
result.push({
card_id: last_id,
side: false,
count: count
});
}
last_id = card_id;
count = 1;
}
}
if (last_id) {
result.push({
card_id: last_id,
side: false,
count: count
});
}
last_id = null;
for (_j = 0, _len1 = side.length; _j < _len1; _j++) {
card_id = side[_j];
if (card_id === last_id) {
count++;
} else {
if (last_id) {
result.push({
card_id: last_id,
side: true,
count: count
});
}
last_id = card_id;
count = 1;
}
}
if (last_id) {
result.push({
card_id: last_id,
side: true,
count: count
});
}
return result;
};
this.encode = function(card_usages) {
var c, card_usage, i, result, _i, _j, _len;
result = '';
for (_i = 0, _len = card_usages.length; _i < _len; _i++) {
card_usage = card_usages[_i];
c = card_usage.side << 29 | card_usage.count << 27 | card_usage.card_id;
for (i = _j = 4; _j >= 0; i = --_j) {
result += this.key.charAt((c >> i * 6) & 0x3F);
}
}
return result;
};
this.deck_url = function(name, card_usages, format) {
return "https://my-card.in/decks/new" + (format ? '.' + format : '') + "?name=" + (encodeURIComponent(name)) + "&cards=" + (this.encode(card_usages));
};
this.deck_url_short = function(name, card_usages, callback) {
request = require('request');
return request(this.deck_url(name, card_usages, 'short.url'), function(error, response, body) {
return callback(body);
});
};
}).call(this);
/*
//@ sourceMappingURL=mycard.map
*/
{
"version": 3,
"file": "mycard.js",
"sourceRoot": "",
"sources": [
"mycard.coffee"
],
"names": [],
"mappings": ";AAAA;CAAA,KAAA,CAAA;;CAAA,CAAA,CAAU,IAAV,EAAU;;CAAV,CACA,CAAA,CAAC,+DADD;;CAAA,CAEA,CAA+B,CAA9B,KAA+B,kBAAhC;CACE,OAAA,4CAAA;CAAA,CAAA,CAAS,CAAT,EAAA;CAAA,EACU,CAAV,GAAA;AACA,CAAA,QAAA,kCAAA;0BAAA;CACE,GAAG,CAAW,CAAd,CAAG;AACD,CAAA,CAAA,GAAA,GAAA;MADF,EAAA;CAGE,GAA6D,GAA7D,CAAA;CAAA,GAAA,EAAM,IAAN;CAAY,CAAU,KAAT,KAAA;CAAD,CAAyB,EAAN,CAAnB,OAAmB;CAAnB,CAAuC,GAAP,OAAA;CAA5C,WAAA;UAAA;CAAA,EACU,IAAV,CAAA;CADA,EAEQ,EAAR,GAAA;QANJ;CAAA,IAFA;CASA,GAAA,GAAA;CAAA,GAAA,EAAA;CAAY,CAAU,KAAT,CAAA;CAAD,CAAyB,EAAN,CAAnB,GAAmB;CAAnB,CAAuC,GAAP,GAAA;CAA5C,OAAA;MATA;CAAA,EAUU,CAAV,GAAA;AACA,CAAA,QAAA,oCAAA;0BAAA;CACE,GAAG,CAAW,CAAd,CAAG;AACD,CAAA,CAAA,GAAA,GAAA;MADF,EAAA;CAGE,GAA4D,GAA5D,CAAA;CAAA,GAAA,EAAM,IAAN;CAAY,CAAU,KAAT,KAAA;CAAD,CAAyB,EAAN,QAAA;CAAnB,CAAsC,GAAP,OAAA;CAA3C,WAAA;UAAA;CAAA,EACU,IAAV,CAAA;CADA,EAEQ,EAAR,GAAA;QANJ;CAAA,IAXA;CAkBA,GAAA,GAAA;CAAA,GAAA,EAAA;CAAY,CAAU,KAAT,CAAA;CAAD,CAAyB,EAAN,IAAA;CAAnB,CAAsC,GAAP,GAAA;CAA3C,OAAA;MAlBA;CAD6B,UAoB7B;CAtBF,EAE+B;;CAF/B,CAwBA,CAAU,CAAT,EAAD,GAAW,EAAD;CACR,OAAA,8BAAA;CAAA,CAAA,CAAS,CAAT,EAAA;AACA,CAAA,QAAA,yCAAA;oCAAA;CACE,CAAI,CAAA,CAAA,CAAwB,CAA5B,CAAA,GAAc;AACd,CAAA,EAAA,QAAS,kBAAT;CACE,EAAc,CAAJ,EAAV,EAAA;CADF,MAFF;CAAA,IADA;CADQ,UAMR;CA9BF,EAwBU;;CAxBV,CAgCA,CAAY,CAAX,EAAW,EAAZ,CAAa,EAAD;CACuB,CAAH,CAAA,CAA4C,EAA5C,EAA7B,CAAA,EAAA,OAAyE,YAAzE;CAjCH,EAgCY;;CAhCZ,CAmCA,CAAkB,CAAjB,IAAiB,CAAC,EAAD,GAAlB;CACE,EAAU,CAAV,GAAA,EAAU;CACF,CAAgB,CAA2B,CAA1C,CAA0C,EAAnD,CAAQ,CAA4C,EAApD;CACW,GAAT,IAAA,KAAA;CADF,IAAmD;CArCrD,EAmCkB;CAnClB"
}
\ No newline at end of file
...@@ -16,7 +16,6 @@ ...@@ -16,7 +16,6 @@
"underscore": "*", "underscore": "*",
"underscore.string": "*", "underscore.string": "*",
"freeport": "*", "freeport": "*",
"struct": "*",
"inotify": "*", "inotify": "*",
"request": "*", "request": "*",
"mongoose": "*" "mongoose": "*"
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
"PLAYER_INFO": "CTOS_PlayerInfo", "PLAYER_INFO": "CTOS_PlayerInfo",
"JOIN_GAME":"CTOS_JoinGame", "JOIN_GAME":"CTOS_JoinGame",
"UPDATE_DECK": "deck", "UPDATE_DECK": "deck",
"CHANGE_SIDE":"",
"CHAT": "chat" "CHAT": "chat"
}, },
"STOC":{ "STOC":{
......
...@@ -3,6 +3,17 @@ _.str = require 'underscore.string' ...@@ -3,6 +3,17 @@ _.str = require 'underscore.string'
_.mixin(_.str.exports()); _.mixin(_.str.exports());
spawn = require('child_process').spawn spawn = require('child_process').spawn
ygopro = require './ygopro.js' ygopro = require './ygopro.js'
bunyan = require 'bunyan'
settings = require './config.json'
log = bunyan.createLogger name: "mycard-room"
if settings.modules.database
mongoose = require 'mongoose'
mongoose.connect(settings.modules.database);
User = require './user.js'
Deck = require './deck.js'
Match = require './match.js'
class Room class Room
#name #name
#port #port
...@@ -14,21 +25,36 @@ class Room ...@@ -14,21 +25,36 @@ class Room
@all = [] @all = []
@find_or_create_by_name: (name)-> @find_or_create_by_name: (name)->
result = @find_by_name(name) ? new Room(name) @find_by_name(name) ? new Room(name)
@find_by_name: (name)-> @find_by_name: (name)->
_.find @all, (room)-> result = _.find @all, (room)->
room.name == name room.name == name
log.info 'find_by_name', name, result
result
@find_by_port: (port)-> @find_by_port: (port)->
_.find @all, (room)-> _.find @all, (room)->
room.port == port room.port == port
@validate: (name)->
client_name_and_pass = name.split('$',2)
client_name = client_name_and_pass[0]
client_pass = client_name_and_pass[1]
!_.find Room.all, (room)->
room_name_and_pass = room.name.split('$',2)
room_name = room_name_and_pass[0]
room_pass = room_name_and_pass[1]
client_name == room_name and client_pass != room_pass
constructor: (name) -> constructor: (name) ->
@name = name @name = name
@alive = true @alive = true
@players = [] @players = []
@status = 'starting' @status = 'starting'
@established = false
@watcher_buffers = []
@watchers = []
Room.all.push this Room.all.push this
if name[0...2] == 'M#' if name[0...2] == 'M#'
...@@ -43,25 +69,114 @@ class Room ...@@ -43,25 +69,114 @@ class Room
@process = spawn './ygopro', param, cwd: 'ygocore' @process = spawn './ygopro', param, cwd: 'ygocore'
@process.on 'exit', (code)=> @process.on 'exit', (code)=>
console.log "room process #{@port} exited with code #{code}" log.info 'room-exit', this.name, this.port, code
@disconnector = 'server' unless @disconnector
this.delete() this.delete()
@process.stdout.setEncoding('utf8') @process.stdout.setEncoding('utf8')
@process.stdout.once 'data', (data)=> @process.stdout.once 'data', (data)=>
@established = true @established = true
@port = parseInt data @port = parseInt data
#setTimeout =>
_.each @players, (player)=> _.each @players, (player)=>
player.server.connect @port, '127.0.0.1',=> player.server.connect @port, '127.0.0.1',=>
player.server.write buffer for buffer in player.pre_establish_buffers player.server.write buffer for buffer in player.pre_establish_buffers
player.established = true player.established = true
delete: (room)-> delete: ->
Room.all.splice(_.indexOf(Room.all, room), 1) #积分
return if @deleted
@save_match() if _.startsWith(@name, 'M#') and @started and settings.modules.database
index = _.indexOf(Room.all, this)
Room.all.splice(index, 1) unless index == -1
@deleted = true
toString: -> toString: ->
"room: #{@name} #{@port} #{@alive ? 'alive' : 'not-alive'} #{@dueling ? 'dueling' : 'not-dueling'} [#{("client #{typeof player.client} server #{typeof player.server} #{player.name} #{player.pos}. " for player in @players)}] #{JSON.stringify @pos_name}" "room: #{@name} #{@port} #{@alive ? 'alive' : 'not-alive'} #{@dueling ? 'dueling' : 'not-dueling'} [#{("client #{typeof player.client} server #{typeof player.server} #{player.name} #{player.pos}. " for player in @players)}] #{JSON.stringify @pos_name}"
ensure_finish: ()->
#判断match是否正常结束
player_wins = [0,0,0]
for duel in @duels
player_wins[duel.winner] += 1
normal_ended = player_wins[0] >= 2 or player_wins[1] >= 2
if !normal_ended
if @disconnector == 'server'
return false
if @duels.length == 0 or _.last(@duels).reason != 4
@duels.push {winner: 1-@disconnector.pos, reason: 4}
true
save_match: ()->
return unless @ensure_finish()
match_winner = _.last(@duels).winner
User.findOne { name: @dueling_players[0].name }, (err, player0)=>
if(err)
log.error "error when find user", @dueling_players[0].name, err
else if(!player0)
log.error "can't find user ", @dueling_players[0].name
else
User.findOne { name: @dueling_players[1].name }, (err, player1)=>
if(err)
log.error "error when find user", @dueling_players[1].name, err
else if(!player1)
log.error "can't find user ", @dueling_players[1].name
else
#---------------------------------------------------------------------------
#卡组
log.info user: player0._id, card_usages: @dueling_players[0].deck
Deck.findOne user: player0._id, card_usages: @dueling_players[0].deck, (err, deck0)=>
if(err)
log.error "error when find deck"
else if(!deck0)
deck0 = new Deck({name: 'match', user: player0._id, card_usages: @dueling_players[0].deck, used_count: 1, last_used_at: Date.now()})
deck0.save()
else
deck0.used_count++
deck0.last_used_at = Date.now()
deck0.save()
log.info deck0
log.info @dueling_players[0].deck, @dueling_players[1].deck, @dueling_players
Deck.findOne user: player1._id, card_usages: @dueling_players[1].deck, (err, deck1)=>
if(err)
log.error "error when find deck"
else if(!deck1)
deck1 = new Deck({name: 'match', user: player1._id, card_usages: @dueling_players[1].deck, used_count: 1, last_used_at: Date.now()})
deck1.save()
else
deck1.used_count++
deck1.last_used_at = Date.now()
deck1.save()
log.info deck1
Match.create
players: [{user: player0._id, deck: deck0._id}, {user: player1._id, deck: deck1._id}]
duels: @duels
winner: if match_winner == 0 then player0._id else player1._id,
ygopro_version: settings.version
,(err, match)->
log.info err, match
#积分
if match_winner == 0
winner = player0
loser = player1
else
winner = player1
loser = player0
log.info('before_settle_result',winner.name, winner.points,loser.name, loser.points)
winner.points += 5
if _.last(@duels).reason == 4
loser.points -= 8
else
loser.points -= 3
log.info('duel_settle_result',winner.name, winner.points,loser.name, loser.points)
winner.save()
loser.save()
connect: (client)-> connect: (client)->
@players.push client @players.push client
...@@ -71,10 +186,18 @@ class Room ...@@ -71,10 +186,18 @@ class Room
client.established = true client.established = true
disconnect: (client, error)-> disconnect: (client, error)->
@players = _.reject @players, (player)-> if client.is_post_watcher
player is client ygopro.stoc_send_chat_to_room this, "#{client.name} #{'退出了观战'}#{if error then ": #{error}" else ''}"
index = _.indexOf(@watchers, client)
@watchers.splice(index, 1) unless index == -1
else
index = _.indexOf(@players, client)
@players.splice(index, 1) unless index == -1
if @players.length
ygopro.stoc_send_chat_to_room this, "#{client.name} #{'离开了游戏'}#{if error then ": #{error}" else ''}"
else
@process.kill()
this.delete()
for player in @players
ygopro.stoc_send_chat(player, "#{client.name} 离开了游戏#{if error then ": #{error}" else ''}")
module.exports = Room module.exports = Room
\ No newline at end of file
// Generated by CoffeeScript 1.6.3 // Generated by CoffeeScript 1.6.3
(function() { (function() {
var Room, spawn, ygopro, _; var Deck, Match, Room, User, bunyan, log, mongoose, settings, spawn, ygopro, _;
_ = require('underscore'); _ = require('underscore');
...@@ -12,18 +12,37 @@ ...@@ -12,18 +12,37 @@
ygopro = require('./ygopro.js'); ygopro = require('./ygopro.js');
bunyan = require('bunyan');
settings = require('./config.json');
log = bunyan.createLogger({
name: "mycard-room"
});
if (settings.modules.database) {
mongoose = require('mongoose');
mongoose.connect(settings.modules.database);
User = require('./user.js');
Deck = require('./deck.js');
Match = require('./match.js');
}
Room = (function() { Room = (function() {
Room.all = []; Room.all = [];
Room.find_or_create_by_name = function(name) { Room.find_or_create_by_name = function(name) {
var result, _ref; var _ref;
return result = (_ref = this.find_by_name(name)) != null ? _ref : new Room(name); return (_ref = this.find_by_name(name)) != null ? _ref : new Room(name);
}; };
Room.find_by_name = function(name) { Room.find_by_name = function(name) {
return _.find(this.all, function(room) { var result;
result = _.find(this.all, function(room) {
return room.name === name; return room.name === name;
}); });
log.info('find_by_name', name, result);
return result;
}; };
Room.find_by_port = function(port) { Room.find_by_port = function(port) {
...@@ -32,6 +51,20 @@ ...@@ -32,6 +51,20 @@
}); });
}; };
Room.validate = function(name) {
var client_name, client_name_and_pass, client_pass;
client_name_and_pass = name.split('$', 2);
client_name = client_name_and_pass[0];
client_pass = client_name_and_pass[1];
return !_.find(Room.all, function(room) {
var room_name, room_name_and_pass, room_pass;
room_name_and_pass = room.name.split('$', 2);
room_name = room_name_and_pass[0];
room_pass = room_name_and_pass[1];
return client_name === room_name && client_pass !== room_pass;
});
};
function Room(name) { function Room(name) {
var param, var param,
_this = this; _this = this;
...@@ -39,6 +72,9 @@ ...@@ -39,6 +72,9 @@
this.alive = true; this.alive = true;
this.players = []; this.players = [];
this.status = 'starting'; this.status = 'starting';
this.established = false;
this.watcher_buffers = [];
this.watchers = [];
Room.all.push(this); Room.all.push(this);
if (name.slice(0, 2) === 'M#') { if (name.slice(0, 2) === 'M#') {
param = [0, 0, 0, 1, 'F', 'F', 'F', 8000, 5, 1]; param = [0, 0, 0, 1, 'F', 'F', 'F', 8000, 5, 1];
...@@ -54,7 +90,10 @@ ...@@ -54,7 +90,10 @@
cwd: 'ygocore' cwd: 'ygocore'
}); });
this.process.on('exit', function(code) { this.process.on('exit', function(code) {
console.log("room process " + _this.port + " exited with code " + code); log.info('room-exit', _this.name, _this.port, code);
if (!_this.disconnector) {
_this.disconnector = 'server';
}
return _this["delete"](); return _this["delete"]();
}); });
this.process.stdout.setEncoding('utf8'); this.process.stdout.setEncoding('utf8');
...@@ -75,8 +114,19 @@ ...@@ -75,8 +114,19 @@
}); });
} }
Room.prototype["delete"] = function(room) { Room.prototype["delete"] = function() {
return Room.all.splice(_.indexOf(Room.all, room), 1); var index;
if (this.deleted) {
return;
}
if (_.startsWith(this.name, 'M#') && this.started && settings.modules.database) {
this.save_match();
}
index = _.indexOf(Room.all, this);
if (index !== -1) {
Room.all.splice(index, 1);
}
return this.deleted = true;
}; };
Room.prototype.toString = function() { Room.prototype.toString = function() {
...@@ -97,6 +147,141 @@ ...@@ -97,6 +147,141 @@
}).call(this)) + "] " + (JSON.stringify(this.pos_name)); }).call(this)) + "] " + (JSON.stringify(this.pos_name));
}; };
Room.prototype.ensure_finish = function() {
var duel, normal_ended, player_wins, _i, _len, _ref;
player_wins = [0, 0, 0];
_ref = this.duels;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
duel = _ref[_i];
player_wins[duel.winner] += 1;
}
normal_ended = player_wins[0] >= 2 || player_wins[1] >= 2;
if (!normal_ended) {
if (this.disconnector === 'server') {
return false;
}
if (this.duels.length === 0 || _.last(this.duels).reason !== 4) {
this.duels.push({
winner: 1 - this.disconnector.pos,
reason: 4
});
}
}
return true;
};
Room.prototype.save_match = function() {
var match_winner,
_this = this;
if (!this.ensure_finish()) {
return;
}
match_winner = _.last(this.duels).winner;
return User.findOne({
name: this.dueling_players[0].name
}, function(err, player0) {
if (err) {
return log.error("error when find user", _this.dueling_players[0].name, err);
} else if (!player0) {
return log.error("can't find user ", _this.dueling_players[0].name);
} else {
return User.findOne({
name: _this.dueling_players[1].name
}, function(err, player1) {
var loser, winner;
if (err) {
return log.error("error when find user", _this.dueling_players[1].name, err);
} else if (!player1) {
return log.error("can't find user ", _this.dueling_players[1].name);
} else {
log.info({
user: player0._id,
card_usages: _this.dueling_players[0].deck
});
Deck.findOne({
user: player0._id,
card_usages: _this.dueling_players[0].deck
}, function(err, deck0) {
if (err) {
log.error("error when find deck");
} else if (!deck0) {
deck0 = new Deck({
name: 'match',
user: player0._id,
card_usages: _this.dueling_players[0].deck,
used_count: 1,
last_used_at: Date.now()
});
deck0.save();
} else {
deck0.used_count++;
deck0.last_used_at = Date.now();
deck0.save();
}
log.info(deck0);
log.info(_this.dueling_players[0].deck, _this.dueling_players[1].deck, _this.dueling_players);
return Deck.findOne({
user: player1._id,
card_usages: _this.dueling_players[1].deck
}, function(err, deck1) {
if (err) {
log.error("error when find deck");
} else if (!deck1) {
deck1 = new Deck({
name: 'match',
user: player1._id,
card_usages: _this.dueling_players[1].deck,
used_count: 1,
last_used_at: Date.now()
});
deck1.save();
} else {
deck1.used_count++;
deck1.last_used_at = Date.now();
deck1.save();
}
log.info(deck1);
return Match.create({
players: [
{
user: player0._id,
deck: deck0._id
}, {
user: player1._id,
deck: deck1._id
}
],
duels: _this.duels,
winner: match_winner === 0 ? player0._id : player1._id,
ygopro_version: settings.version
}, function(err, match) {
return log.info(err, match);
});
});
});
if (match_winner === 0) {
winner = player0;
loser = player1;
} else {
winner = player1;
loser = player0;
}
log.info('before_settle_result', winner.name, winner.points, loser.name, loser.points);
winner.points += 5;
if (_.last(_this.duels).reason === 4) {
loser.points -= 8;
} else {
loser.points -= 3;
}
log.info('duel_settle_result', winner.name, winner.points, loser.name, loser.points);
winner.save();
return loser.save();
}
});
}
});
};
Room.prototype.connect = function(client) { Room.prototype.connect = function(client) {
this.players.push(client); this.players.push(client);
if (this.established) { if (this.established) {
...@@ -113,17 +298,25 @@ ...@@ -113,17 +298,25 @@
}; };
Room.prototype.disconnect = function(client, error) { Room.prototype.disconnect = function(client, error) {
var player, _i, _len, _ref, _results; var index;
this.players = _.reject(this.players, function(player) { if (client.is_post_watcher) {
return player === client; ygopro.stoc_send_chat_to_room(this, "" + client.name + " " + '退出了观战' + (error ? ": " + error : ''));
}); index = _.indexOf(this.watchers, client);
_ref = this.players; if (index !== -1) {
_results = []; return this.watchers.splice(index, 1);
for (_i = 0, _len = _ref.length; _i < _len; _i++) { }
player = _ref[_i]; } else {
_results.push(ygopro.stoc_send_chat(player, "" + client.name + " 离开了游戏" + (error ? ": " + error : ''))); index = _.indexOf(this.players, client);
if (index !== -1) {
this.players.splice(index, 1);
}
if (this.players.length) {
return ygopro.stoc_send_chat_to_room(this, "" + client.name + " " + '离开了游戏' + (error ? ": " + error : ''));
} else {
this.process.kill();
return this["delete"]();
}
} }
return _results;
}; };
return Room; return Room;
......
...@@ -6,5 +6,5 @@ ...@@ -6,5 +6,5 @@
"room.coffee" "room.coffee"
], ],
"names": [], "names": [],
"mappings": "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" "mappings": "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"
} }
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
settings = require './config.json'
mongoose = require 'mongoose'
User = mongoose.model 'User',
name: String
points: Number
module.exports = User
\ No newline at end of file
// Generated by CoffeeScript 1.6.3
(function() {
var User, mongoose, settings;
settings = require('./config.json');
mongoose = require('mongoose');
User = mongoose.model('User', {
name: String,
points: Number
});
module.exports = User;
}).call(this);
/*
//@ sourceMappingURL=user.map
*/
{
"version": 3,
"file": "user.js",
"sourceRoot": "",
"sources": [
"user.coffee"
],
"names": [],
"mappings": ";AAAA;CAAA,KAAA,kBAAA;;CAAA,CAAA,CAAW,IAAA,CAAX,OAAW;;CAAX,CAEA,CAAW,IAAA,CAAX,EAAW;;CAFX,CAGA,CAAO,CAAP,CAAO,CAAA,EAAQ;CACb,CAAM,EAAN,EAAA;CAAA,CACQ,EAAR,EAAA;CALF,GAGO;;CAHP,CAOA,CAAiB,CAPjB,EAOM,CAAN;CAPA"
}
\ No newline at end of file
{
"0":"投降",
"1":"LP变成0",
"2":"没有卡可抽",
"3":"超时",
"4":"失去连接",
"16":"「被封印的艾克佐迪亚」效果胜利",
"17": "「终焉的倒计时」效果胜利",
"18": "「毒蛇神 维诺米纳迦」效果胜利",
"19": "「光之创造神 哈拉克提」效果胜利",
"20": "「究极封印神 艾克佐迪奥斯」效果胜利",
"21": "「通灵盘」效果胜利",
"22": "「最终一战!」效果胜利",
"23": "「No.88 机关傀儡-命运狮子」效果胜利",
"32": "由于「%ls」的效果获得比赛胜利"
}
\ No newline at end of file
...@@ -4,6 +4,7 @@ http = require 'http' ...@@ -4,6 +4,7 @@ http = require 'http'
url = require 'url' url = require 'url'
path = require 'path' path = require 'path'
fs = require 'fs' fs = require 'fs'
execFile = require('child_process').execFile
#三方库 #三方库
_ = require 'underscore' _ = require 'underscore'
...@@ -13,18 +14,31 @@ _.mixin(_.str.exports()); ...@@ -13,18 +14,31 @@ _.mixin(_.str.exports());
Inotify = require('inotify').Inotify Inotify = require('inotify').Inotify
request = require 'request' request = require 'request'
bunyan = require 'bunyan'
#配置文件
settings = require './config.json'
#组件 #组件
ygopro = require './ygopro.js' ygopro = require './ygopro.js'
mycard = require './mycard.js'
Room = require './room.js' Room = require './room.js'
User = require './user.js' if settings.modules.database
Deck = require './deck.js' if settings.modules.database
victories = require './victories.json'
#配置文件
settings = require './config.json' #本机IP端口设置
#debug模式 端口号+1 #debug模式 端口号+1
debug = false debug = false
log = null
if process.argv[2] == '--debug' if process.argv[2] == '--debug'
settings.port++ settings.port++
settings.http_port++ settings.modules.http.port++ if settings.modules.http
log = bunyan.createLogger name: "mycard-debug"
else
log = bunyan.createLogger name: "mycard"
#网络连接 #网络连接
net.createServer (client) -> net.createServer (client) ->
...@@ -33,33 +47,35 @@ net.createServer (client) -> ...@@ -33,33 +47,35 @@ net.createServer (client) ->
#释放处理 #释放处理
client.on 'close', (had_error) -> client.on 'close', (had_error) ->
console.log "client closed #{had_error}" log.info "client closed", client.name, had_error
client.room.disconnector = client if client.room and client.room.started and client in client.room.dueling_players and !client.room.disconnector
unless client.closed unless client.closed
client.room.disconnect(client) if client.room
client.closed = true client.closed = true
client.room.disconnect(client) if client.room
server.end() server.end()
client.on 'error', (error)-> client.on 'error', (error)->
console.log "client error #{error}" log.info "client error", client.name, error
client.room.disconnector = client if client.room and client.room.started and client in client.room.dueling_players and !client.room.disconnector
unless client.closed unless client.closed
client.room.disconnect(client, error) if client.room
client.closed = error client.closed = error
client.room.disconnect(client, error) if client.room
server.end() server.end()
server.on 'close', (had_error) -> server.on 'close', (had_error) ->
console.log "server closed #{had_error}" log.info "server closed", client.name, had_error
server.closed = true unless server.closed server.closed = true unless server.closed
client.room.disconnector = 'server' if client.room and client.room.started and client in client.room.dueling_players and !client.room.disconnector
unless client.closed unless client.closed
ygopro.stoc_send_chat(client, "服务器关闭了连接") ygopro.stoc_send_chat(client, "服务器关闭了连接")
client.closed = true
client.end() client.end()
server.on 'error', (error)-> server.on 'error', (error)->
console.log "server error #{error}" log.info "server error", client.name, error
server.closed = error server.closed = error
client.room.disconnector = 'server' if client.room and client.room.started and client in client.room.dueling_players and !client.room.disconnector
unless client.closed unless client.closed
ygopro.stoc_send_chat(client, "服务器错误: #{error}") ygopro.stoc_send_chat(client, "服务器错误: #{error}")
client.closed = true
client.end() client.end()
#需要重构 #需要重构
...@@ -71,8 +87,16 @@ net.createServer (client) -> ...@@ -71,8 +87,16 @@ net.createServer (client) ->
client.pre_establish_buffers = new Array() client.pre_establish_buffers = new Array()
client.on 'data', (data) -> client.on 'data', (data) ->
if client.is_post_watcher
client.room.watcher.write data
else
ctos_buffer = Buffer.concat([ctos_buffer, data], ctos_buffer.length + data.length) #buffer的错误使用方式,好孩子不要学 ctos_buffer = Buffer.concat([ctos_buffer, data], ctos_buffer.length + data.length) #buffer的错误使用方式,好孩子不要学
#console.log data
if client.established
server.write data
else
client.pre_establish_buffers.push data
while true while true
if ctos_message_length == 0 if ctos_message_length == 0
if ctos_buffer.length >= 2 if ctos_buffer.length >= 2
...@@ -86,13 +110,14 @@ net.createServer (client) -> ...@@ -86,13 +110,14 @@ net.createServer (client) ->
break break
else else
if ctos_buffer.length >= 2 + ctos_message_length if ctos_buffer.length >= 2 + ctos_message_length
#console.log "CTOS", ygopro.constants.CTOS[ctos_proto]
if ygopro.ctos_follows[ctos_proto] if ygopro.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 = ygopro.structs[ygopro.proto_structs.CTOS[ygopro.constants.CTOS[ctos_proto]]] if struct = ygopro.structs[ygopro.proto_structs.CTOS[ygopro.constants.CTOS[ctos_proto]]]
struct._setBuff(b) struct._setBuff(b)
setTimeout ygopro.ctos_follows[ctos_proto].callback, 0, b, _.clone(struct.fields), client, server ygopro.ctos_follows[ctos_proto].callback b, _.clone(struct.fields), client, server
else else
setTimeout ygopro.ctos_follows[ctos_proto].callback, 0, b, null, client, server ygopro.ctos_follows[ctos_proto].callback b, null, client, server
ctos_buffer = ctos_buffer.slice(2 + ctos_message_length) ctos_buffer = ctos_buffer.slice(2 + ctos_message_length)
ctos_message_length = 0 ctos_message_length = 0
...@@ -100,12 +125,6 @@ net.createServer (client) -> ...@@ -100,12 +125,6 @@ net.createServer (client) ->
else else
break break
unless ygopro.ctos_follows[ctos_proto] and ygopro.ctos_follows[ctos_proto].synchronous
if client.established
server.write data
else
client.pre_establish_buffers.push data
#服务端到客户端(stoc) #服务端到客户端(stoc)
stoc_buffer = new Buffer(0) stoc_buffer = new Buffer(0)
stoc_message_length = 0 stoc_message_length = 0
...@@ -114,6 +133,9 @@ net.createServer (client) -> ...@@ -114,6 +133,9 @@ net.createServer (client) ->
server.on 'data', (data)-> server.on 'data', (data)->
stoc_buffer = Buffer.concat([stoc_buffer, data], stoc_buffer.length + data.length) #buffer的错误使用方式,好孩子不要学 stoc_buffer = Buffer.concat([stoc_buffer, data], stoc_buffer.length + data.length) #buffer的错误使用方式,好孩子不要学
#unless ygopro.stoc_follows[stoc_proto] and ygopro.stoc_follows[stoc_proto].synchronous
client.write data
while true while true
if stoc_message_length == 0 if stoc_message_length == 0
if stoc_buffer.length >= 2 if stoc_buffer.length >= 2
...@@ -127,13 +149,14 @@ net.createServer (client) -> ...@@ -127,13 +149,14 @@ net.createServer (client) ->
break break
else else
if stoc_buffer.length >= 2 + stoc_message_length if stoc_buffer.length >= 2 + stoc_message_length
#console.log "STOC", ygopro.constants.STOC[stoc_proto]
if ygopro.stoc_follows[stoc_proto] if ygopro.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 = ygopro.structs[ygopro.proto_structs.STOC[ygopro.constants.STOC[stoc_proto]]] if struct = ygopro.structs[ygopro.proto_structs.STOC[ygopro.constants.STOC[stoc_proto]]]
struct._setBuff(b) struct._setBuff(b)
setImmediate ygopro.stoc_follows[stoc_proto].callback, b, _.clone(struct.fields), client, server ygopro.stoc_follows[stoc_proto].callback b, _.clone(struct.fields), client, server
else else
setImmediate ygopro.stoc_follows[stoc_proto].callback, b, null, client, server ygopro.stoc_follows[stoc_proto].callback b, null, client, server
stoc_buffer = stoc_buffer.slice(2 + stoc_message_length) stoc_buffer = stoc_buffer.slice(2 + stoc_message_length)
stoc_message_length = 0 stoc_message_length = 0
...@@ -141,11 +164,8 @@ net.createServer (client) -> ...@@ -141,11 +164,8 @@ net.createServer (client) ->
else else
break break
#unless ygopro.stoc_follows[stoc_proto] and ygopro.stoc_follows[stoc_proto].synchronous
client.write data
.listen settings.port, -> .listen settings.port, ->
console.log "server started on #{settings.ip}:#{settings.port}" log.info "server started", settings.ip, settings.port
#功能模块 #功能模块
...@@ -153,6 +173,7 @@ ygopro.ctos_follow 'PLAYER_INFO', true, (buffer, info, client, server)-> ...@@ -153,6 +173,7 @@ ygopro.ctos_follow 'PLAYER_INFO', true, (buffer, info, client, server)->
client.name = info.name #在创建room之前暂存 client.name = info.name #在创建room之前暂存
ygopro.ctos_follow 'JOIN_GAME', false, (buffer, info, client, server)-> ygopro.ctos_follow 'JOIN_GAME', false, (buffer, info, client, server)->
#log.info info
if info.version != settings.version if info.version != settings.version
ygopro.stoc_send client, 'ERROR_MSG',{ ygopro.stoc_send client, 'ERROR_MSG',{
msg: 4 msg: 4
...@@ -166,12 +187,18 @@ ygopro.ctos_follow 'JOIN_GAME', false, (buffer, info, client, server)-> ...@@ -166,12 +187,18 @@ ygopro.ctos_follow 'JOIN_GAME', false, (buffer, info, client, server)->
code: 2 code: 2
} }
client.end() client.end()
else if info.pass == '[INCORRECT]' #模拟房间密码验证 else if !Room.validate(info.pass)
#ygopro.stoc_send client, 'ERROR_MSG',{
# msg: 1
# code: 1 #这返错有问题,直接双ygopro直连怎么都正常,在这里就经常弹不出提示
#}
ygopro.stoc_send_chat(client,"房间密码不正确")
ygopro.stoc_send client, 'ERROR_MSG',{ ygopro.stoc_send client, 'ERROR_MSG',{
msg: 1 msg: 1
code: 1 #这返错有问题,直接双ygopro直连怎么都正常,在服务器上就经常弹不出提示 code: 2
} }
client.end() client.end()
else if client.name == '[INCORRECT]' #模拟用户验证 else if client.name == '[INCORRECT]' #模拟用户验证
ygopro.stoc_send client, 'ERROR_MSG',{ ygopro.stoc_send client, 'ERROR_MSG',{
msg: 1 msg: 1
...@@ -179,89 +206,96 @@ ygopro.ctos_follow 'JOIN_GAME', false, (buffer, info, client, server)-> ...@@ -179,89 +206,96 @@ ygopro.ctos_follow 'JOIN_GAME', false, (buffer, info, client, server)->
} }
client.end() client.end()
else else
log.info 'join_game',info.pass, client.name
client.room = Room.find_or_create_by_name(info.pass) client.room = Room.find_or_create_by_name(info.pass)
if client.room.started
if settings.modules.post_start_watching
client.is_post_watcher = true
ygopro.stoc_send_chat_to_room client.room, "#{client.name} 加入了观战"
client.room.watchers.push client
for buffer in client.room.watcher_buffers
client.write buffer
ygopro.stoc_send_chat client, "观战中."
else
ygopro.stoc_send_chat(client,"决斗已开始")
ygopro.stoc_send client, 'ERROR_MSG',{
msg: 1
code: 2
}
client.end()
else
client.room.connect(client) client.room.connect(client)
###################################################################################################################### ######################################################################################################################
#欢迎信息
ygopro.stoc_follow 'JOIN_GAME', false, (buffer, info, client, server)-> ygopro.stoc_follow 'JOIN_GAME', false, (buffer, info, client, server)->
ygopro.stoc_send client, 'CHAT', { #欢迎信息
player: 8 if settings.modules.welcome
msg: "Mycard Debugging Server" ygopro.stoc_send_chat client, settings.modules.welcome
if settings.modules.database
if _.startsWith(client.room.name, 'M#')
User.findOne { name: client.name }, (err, user)->
if !user
user = new User({name: client.name, points: 0})
user.save()
User.count {points:{$gt:user.points}}, (err, count)->
rank = count + 1
ygopro.stoc_send_chat(client, "积分系统测试中,你现在有#{user.points}点积分,排名#{rank},这些积分以后正式使用时会重置")
if settings.modules.post_start_watching and !client.room.watcher
client.room.watcher = watcher = net.connect client.room.port, ->
ygopro.ctos_send watcher, 'PLAYER_INFO', {
name: "the Big Brother"
} }
ygopro.stoc_send client, 'CHAT', { ygopro.ctos_send watcher, 'JOIN_GAME', {
player: 8 version: settings.version,
msg: "这里是测试中的新服务器, 还不稳定, 随时可能崩溃, 遇到意外请淡定\n ˉˉˉˉˉ" gameid: 2577,
some_unknown_mysterious_fucking_thing: 0
pass: ""
} }
ygopro.ctos_send watcher, 'HS_TOOBSERVER'
watcher.on 'data', (data)->
client.room.watcher_buffers.push data
for w in client.room.watchers
w.write data
#登场台词 #登场台词
dialogues = {} if settings.modules.dialogues
request dialogues = {}
url: 'https://my-card.in/dialogues.json' request
url: settings.modules.dialogues
json: true json: true
, (error, response, body)-> , (error, response, body)->
if _.isString body if _.isString body
console.log "[WARN]dialogues bad json #{body}" log.warn "dialogues bad json", body
else else
console.log "loaded #{_.size body} dialogues" log.info "dialogues loaded", _.size body
dialogues = body dialogues = body
ygopro.stoc_follow 'GAME_MSG', false, (buffer, info, client, server)-> ygopro.stoc_follow 'GAME_MSG', false, (buffer, info, client, server)->
msg = buffer.readInt8(0) msg = buffer.readInt8(0)
if ygopro.constants.MSG[msg] == 'START'
playertype = buffer.readUInt8(1)
client.is_first = !(playertype & 0xf);
if 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)
log.info {winner: pos, reason: reason}
client.room.duels.push {winner: pos, reason: reason}
#登场台词
if settings.modules.dialogues
if ygopro.constants.MSG[msg] == 'SUMMONING' or ygopro.constants.MSG[msg] == 'SPSUMMONING' if ygopro.constants.MSG[msg] == 'SUMMONING' or ygopro.constants.MSG[msg] == 'SPSUMMONING'
card = buffer.readUInt32LE(1) card = buffer.readUInt32LE(1)
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 ygopro.stoc_send_chat client, line
#积分
###
if ygopro.constants.MSG[msg] == 'WIN'
room = Room.find_by_client(client)
if !room
console.log "[WARN]win: can't find room by player #{client.player}"
return
if _.startsWith(room.name, 'M#') and room.dueling
room.dueling = false
loser_name = room.pos_name[buffer.readUInt8(1)]
winner_name = room.pos_name[1 - buffer.readUInt8(1)]
#type = buffer.readUInt8(2)
User.findOne { name: winner_name }, (err, winner)->
if(err)
console.log "#{err} when finding user #{winner_name}"
else if(!winner)
console.log "user #{winner_name} not exist"
else
User.findOne { name: loser_name }, (err, loser)->
if(err)
console.log "#{err} when finding user #{loser_name}"
else if(!loser)
console.log "user #{loser_name} not exist"
else
winner.points += 10
loser.points -= 5
winner.save()
loser.save()
console.log "#{winner} 增加10点积分,现在有#{winner.points}点"
console.log "#{loser} 减少5点积分,现在有#{loser.points}点"
#mongoose = require 'mongoose'
#mongoose.connect('mongodb://localhost/mycard');
#User = mongoose.model 'User',
# name: String
# points: Number
#ygopro.stoc_follow 'HS_PLAYER_CHANGE', false, (buffer, info, client, server)->
# console.log 'HS_PLAYER_CHANGE', info
### ###
#房间管理 #房间管理
ygopro.stoc_follow 'HS_PLAYER_ENTER', false, (buffer, info, client, server)-> ygopro.stoc_follow 'HS_PLAYER_ENTER', false, (buffer, info, client, server)->
console.log "PLAYER_ENTER to #{client.name}: #{info.name}, #{info.pos}" #console.log "PLAYER_ENTER to #{client.name}: #{info.name}, #{info.pos}"
#room = client.room #room = client.room
#if !room #if !room
# console.log "[WARN]player_enter: can't find room by player #{client.player}" # console.log "[WARN]player_enter: can't find room by player #{client.player}"
...@@ -271,42 +305,237 @@ ygopro.stoc_follow 'HS_PLAYER_ENTER', false, (buffer, info, client, server)-> ...@@ -271,42 +305,237 @@ ygopro.stoc_follow 'HS_PLAYER_ENTER', false, (buffer, info, client, server)->
ygopro.stoc_follow 'HS_PLAYER_CHANGE', false, (buffer, info, client, server)-> ygopro.stoc_follow 'HS_PLAYER_CHANGE', false, (buffer, info, client, server)->
#client.ready = info.status & 0xF != 0 #client.ready = info.status & 0xF != 0
#client.pos = info.status >> 4 #client.pos = info.status >> 4
console.log "PLAYER_CHANGE to #{client.name}: #{info.status & 0xF != 0}, #{info.status >> 4}" #console.log "PLAYER_CHANGE to #{client.name}: #{info.status & 0xF != 0}, #{info.status >> 4}"
###
ygopro.stoc_follow 'TYPE_CHANGE', false, (buffer, info, client, server)-> ygopro.stoc_follow 'TYPE_CHANGE', false, (buffer, info, client, server)->
selftype = info.type & 0xf; selftype = info.type & 0xf;
is_host = ((info.type >> 4) & 0xf) != 0; is_host = ((info.type >> 4) & 0xf) != 0;
client.is_host = is_host client.is_host = is_host
client.pos = selftype client.pos = selftype
console.log "TYPE_CHANGE to #{client.name}:", info, selftype, is_host #console.log "TYPE_CHANGE to #{client.name}:", info, selftype, is_host
#tip
ygopro.stoc_send_random_tip = (client)->
ygopro.stoc_send_chat client, "Tip: " + tips[Math.floor(Math.random() * tips.length)] if tips
tips = null
request
url: settings.modules.tips
json: true
, (error, response, body)->
tips = body
log.info "tips loaded", tips.length
ygopro.stoc_follow 'DUEL_START', false, (buffer, info, client, server)->
unless client.room.started #first start
client.room.started = true
client.room.duels = []
client.room.dueling_players = []
for player in client.room.players when player.pos != 7
client.room.dueling_players[player.pos] = player
player.deck = mycard.load_card_usages_from_cards(player.main, player.side)
if !client.room.dueling_players[0] or !client.room.dueling_players[1]
log.error 'incomplete room', client.room.dueling_players, client.room.players
if settings.modules.tips
ygopro.stoc_send_random_tip(client)
ygopro.ctos_follow 'CHAT', false, (buffer, info, client, server)->
switch _.trim(info.msg)
when '/ping'
execFile 'ss', ['-it', "dst #{client.remoteAddress}:#{client.remotePort}"], (error, stdout, stderr)->
if error
ygopro.stoc_send_chat_to_room client.room, error
else
line = _.lines(stdout)[2]
if line.indexOf('rtt') != -1
ygopro.stoc_send_chat_to_room client.room, line
else
log.warn 'ping', stdout
ygopro.stoc_send_chat_to_room client.room, stdout
when '/ranktop'
if settings.modules.database
User.find null, null, { sort: { points : -1 }, limit: 8 }, (err, users)->
if err
return log.error 'ranktop', err
for index, user of users
ygopro.stoc_send_chat client, [parseInt(index)+1, user.points, user.name].join(' ')
when '/help'
ygopro.stoc_send_chat(client,"Mycard MatchServer 指令帮助")
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
#发送卡组
when '/senddeck'
if client.deck?
ygopro.stoc_send_chat(client, "正在读取卡组信息... ")
mycard.deck_url_short client.name, client.deck, (url)->
ygopro.stoc_send_chat_to_room(client.room, "卡组链接: " + url)
else
ygopro.stoc_send_chat_to_room(client.room, "读取卡组信息失败")
when '/admin showroom'
log.info client.room
ygopro.ctos_follow 'UPDATE_DECK', false, (buffer, info, client, server)->
log.info info
main = (info.deckbuf[i] for i in [0...info.mainc])
side = (info.deckbuf[i] for i in [info.mainc...info.mainc+info.sidec])
client.main = main
client.side = side
if settings.modules.skip_empty_side
ygopro.stoc_follow 'CHANGE_SIDE', false, (buffer, info, client, server)->
if not _.any(client.deck, (card_usage)->card_usage.side)
ygopro.ctos_send server, 'UPDATE_DECK', {
mainc: client.main.length,
sidec: 0,
deckbuf: client.main
}
ygopro.stoc_send_chat client, '等待更换副卡组中...'
###
# 开包大战
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
#房间数量 ygopro.ctos_follow 'UPDATE_DECK', false, (buffer, info, client, server)->
http.createServer (request, response)-> ygopro.ctos_send server, 'HS_NOTREADY'
#http://122.0.65.70:7922/?operation=getroomjson
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)]
ygopro.ctos_send server, 'UPDATE_DECK', {
mainc: deck.length,
sidec: 0,
deckbuf: deck
}
ygopro.ctos_send server, 'HS_READY'
###
#http
if settings.modules.http
level_points = require './level_points.json'
waiting = [[]]
for i of level_points
waiting.push []
log.info 'level_points loaded', level_points
http.createServer (request, response)->
#http://122.0.65.70:7922/?operation=getroomjson
url = url.parse(request.url) url = url.parse(request.url)
#log.info url
if url.pathname == '/count.json' if url.pathname == '/count.json'
response.writeHead(200); response.writeHead(200);
response.end(Room.all.length.toString()) response.end(Room.all.length.toString())
else if url.pathname == '/match'
if request.headers['authorization']
[name, password] = new Buffer(request.headers['authorization'].split(/\s+/).pop() ? '','base64').toString().split(':')
User.findOne { name: name }, (err, user)->
if !user
user = new User({name: name, points: 0, elo: 1400})
user.save()
level = level_points.length
for index, points of level_points
if user.points < points
level = index
break
response.allowance = 0
waiting[level].push response
request.on 'close', ()->
index = waiting[level].indexOf(response)
waiting[level].splice(index, 1) unless index == -1
else
#log.info 'unauth match'
#response.writeHead(401);
#response.end("请更新mycard到1.2.8版本");
level = 1
response.allowance = 0
waiting[level].push response
request.on 'close', ()->
index = waiting[level].indexOf(response)
waiting[level].splice(index, 1) unless index == -1
else if url.pathname == '/rooms.json' else if url.pathname == '/rooms.json'
response.writeHead(404); response.writeHead(404);
response.end(); response.end();
if url.query == 'operation=getroomjson' else if url.query == 'operation=getroomjson'
response.writeHead(200); response.writeHead(200);
response.end JSON.stringify rooms: (for room in Room.all response.end JSON.stringify rooms: (for room in Room.all when room.established
roomid: room.port.toString(), roomid: room.port.toString(),
roomname: room.name, roomname: room.name.split('$',2)[0],
needpass: false.toString(), needpass: (room.name.indexOf('$') != -1).toString(),
users: (for player in room.players users: (for player in room.players when player.pos?
id: (-1).toString(), id: (-1).toString(),
name: player.name, name: player.name,
pos: player.pos pos: player.pos
), ),
istart: "wait" istart: if room.started then "start" else "wait"
) )
else else
response.writeHead(404); response.writeHead(404);
response.end(); response.end();
.listen settings.http_port .listen settings.modules.http.port
setInterval ()->
for level in [level_points.length..0]
for index, player of waiting[level]
opponent_level = null
opponent = _.find waiting[level], (opponent)->
log.info opponent,player
opponent isnt player
log.info '--------1--------', waiting, opponent
if opponent
opponent_level = level
else if player.allowance > 0
for displacement in [1..player.allowance]
if level+displacement <= level_points.length
opponent = waiting[level+displacement][0]
if opponent
opponent_level = level+displacement
break
if level-displacement >= 0
opponent = waiting[level-displacement][0]
if opponent
opponent_level = level-displacement
break
if opponent
if waiting[level].indexOf(player) == -1 or waiting[opponent_level].indexOf(opponent) == -1
log.info waiting, player, level, opponent, opponent_level
throw 'WTF'
waiting[level].splice(waiting[level].indexOf(player), 1)
waiting[opponent_level].splice(waiting[opponent_level].indexOf(opponent), 1)
index--
room = "mycard://#{settings.ip}:#{settings.port}/M##{_.uniqueId()}$#{_.random(999)}"
log.info 'matched', room
headers = {"Access-Control-Allow-Origin":"*","Content-Type": "text/plain"}
player.writeHead(200, headers)
player.end room
opponent.writeHead(200, headers)
opponent.end room
else
player.allowance++
, 2000
#清理90s没活动的房间 #清理90s没活动的房间
inotify = new Inotify() inotify = new Inotify()
...@@ -325,85 +554,16 @@ inotify.addWatch ...@@ -325,85 +554,16 @@ inotify.addWatch
else if mask & Inotify.IN_MODIFY else if mask & Inotify.IN_MODIFY
room.alive = true room.alive = true
else else
console.log '[warn] event without filename' log.error "event without filename"
setInterval ()-> setInterval ()->
for room in Room.all for room in Room.all
if room.alive if room.alive
room.alive = false room.alive = false
else else
console.log "kill room #{room.port}" log.info "kill room", room.port
for player in room.players for player in room.players
ygopro.stoc_send_chat(player, "由于长时间没有活动被关闭") unless player.closed ygopro.stoc_send_chat(player, "由于长时间没有活动被关闭") unless player.closed
room.process.kill() room.process.kill()
, 900000 , 900000
\ No newline at end of file
#tip
ygopro.stoc_send_tip = (client, tip)->
lines = _.lines(tip)
ygopro.stoc_send_chat(client, "Tip: #{lines[0]}")
for line in lines.slice(1)
ygopro.stoc_send_chat(client, line)
ygopro.stoc_send_random_tip = (client)->
ygopro.stoc_send_tip client, tips[Math.floor(Math.random() * tips.length)] if tips
tips = null
request
url: 'https://my-card.in/tips.json'
json: true
, (error, response, body)->
tips = body
console.log "loaded #{tips.length} tips"
ygopro.stoc_follow 'DUEL_START', false, (buffer, info, client, server)->
ygopro.stoc_send_random_tip(client)
###
room = Room.find_by_client(client)
if !room
console.log "[WARN]duel start: can't find room by player #{client.player}"
return
room.dueling = true
if _.startsWith(room.name, 'M#')
User.findOne { name: client.player }, (err, user)->
if !user
user = new User({name: client.player, points: 0})
user.save()
ygopro.stoc_send_chat(client, "积分系统测试中,你现在有#{user.points}点积分,这些积分以后可能会重置")
###
ygopro.ctos_follow 'CHAT', false, (buffer, info, client, server)->
if _.trim(info.msg) == '/tip'
ygopro.stoc_send_random_tip(client)
###
# 开包大战
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
ygopro.ctos_follow 'UPDATE_DECK', false, (buffer, info, client, server)->
ygopro.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)]
ygopro.ctos_send server, 'UPDATE_DECK', {
mainc: deck.length,
sidec: 0,
deckbuf: deck
}
ygopro.ctos_send server, 'HS_READY'
###
// Generated by CoffeeScript 1.6.3 // Generated by CoffeeScript 1.6.3
(function() { (function() {
var Inotify, Room, debug, dialogues, fs, http, inotify, net, path, request, settings, tips, url, ygopro, _; var Deck, Inotify, Room, User, bunyan, debug, dialogues, execFile, fs, http, i, inotify, level_points, log, mycard, net, path, request, settings, tips, url, victories, waiting, ygopro, _,
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
net = require('net'); net = require('net');
...@@ -12,6 +13,8 @@ ...@@ -12,6 +13,8 @@
fs = require('fs'); fs = require('fs');
execFile = require('child_process').execFile;
_ = require('underscore'); _ = require('underscore');
_.str = require('underscore.string'); _.str = require('underscore.string');
...@@ -22,17 +25,42 @@ ...@@ -22,17 +25,42 @@
request = require('request'); request = require('request');
bunyan = require('bunyan');
settings = require('./config.json');
ygopro = require('./ygopro.js'); ygopro = require('./ygopro.js');
mycard = require('./mycard.js');
Room = require('./room.js'); Room = require('./room.js');
settings = require('./config.json'); if (settings.modules.database) {
User = require('./user.js');
}
if (settings.modules.database) {
Deck = require('./deck.js');
}
victories = require('./victories.json');
debug = false; debug = false;
log = null;
if (process.argv[2] === '--debug') { if (process.argv[2] === '--debug') {
settings.port++; settings.port++;
settings.http_port++; if (settings.modules.http) {
settings.modules.http.port++;
}
log = bunyan.createLogger({
name: "mycard-debug"
});
} else {
log = bunyan.createLogger({
name: "mycard"
});
} }
net.createServer(function(client) { net.createServer(function(client) {
...@@ -40,42 +68,52 @@ ...@@ -40,42 +68,52 @@
server = new net.Socket(); server = new net.Socket();
client.server = server; client.server = server;
client.on('close', function(had_error) { client.on('close', function(had_error) {
console.log("client closed " + had_error); log.info("client closed", client.name, had_error);
if (client.room && client.room.started && __indexOf.call(client.room.dueling_players, client) >= 0 && !client.room.disconnector) {
client.room.disconnector = client;
}
if (!client.closed) { if (!client.closed) {
client.closed = true;
if (client.room) { if (client.room) {
client.room.disconnect(client); client.room.disconnect(client);
} }
client.closed = true;
} }
return server.end(); return server.end();
}); });
client.on('error', function(error) { client.on('error', function(error) {
console.log("client error " + error); log.info("client error", client.name, error);
if (client.room && client.room.started && __indexOf.call(client.room.dueling_players, client) >= 0 && !client.room.disconnector) {
client.room.disconnector = client;
}
if (!client.closed) { if (!client.closed) {
client.closed = error;
if (client.room) { if (client.room) {
client.room.disconnect(client, error); client.room.disconnect(client, error);
} }
client.closed = error;
} }
return server.end(); return server.end();
}); });
server.on('close', function(had_error) { server.on('close', function(had_error) {
console.log("server closed " + had_error); log.info("server closed", client.name, had_error);
if (!server.closed) { if (!server.closed) {
server.closed = true; server.closed = true;
} }
if (client.room && client.room.started && __indexOf.call(client.room.dueling_players, client) >= 0 && !client.room.disconnector) {
client.room.disconnector = 'server';
}
if (!client.closed) { if (!client.closed) {
ygopro.stoc_send_chat(client, "服务器关闭了连接"); ygopro.stoc_send_chat(client, "服务器关闭了连接");
client.closed = true;
return client.end(); return client.end();
} }
}); });
server.on('error', function(error) { server.on('error', function(error) {
console.log("server error " + error); log.info("server error", client.name, error);
server.closed = error; server.closed = error;
if (client.room && client.room.started && __indexOf.call(client.room.dueling_players, client) >= 0 && !client.room.disconnector) {
client.room.disconnector = 'server';
}
if (!client.closed) { if (!client.closed) {
ygopro.stoc_send_chat(client, "服务器错误: " + error); ygopro.stoc_send_chat(client, "服务器错误: " + error);
client.closed = true;
return client.end(); return client.end();
} }
}); });
...@@ -84,18 +122,27 @@ ...@@ -84,18 +122,27 @@
ctos_proto = 0; ctos_proto = 0;
client.pre_establish_buffers = new Array(); client.pre_establish_buffers = new Array();
client.on('data', function(data) { client.on('data', function(data) {
var b, struct; var b, struct, _results;
if (client.is_post_watcher) {
return client.room.watcher.write(data);
} else {
ctos_buffer = Buffer.concat([ctos_buffer, data], ctos_buffer.length + data.length); ctos_buffer = Buffer.concat([ctos_buffer, data], ctos_buffer.length + data.length);
if (client.established) {
server.write(data);
} else {
client.pre_establish_buffers.push(data);
}
_results = [];
while (true) { while (true) {
if (ctos_message_length === 0) { if (ctos_message_length === 0) {
if (ctos_buffer.length >= 2) { if (ctos_buffer.length >= 2) {
ctos_message_length = ctos_buffer.readUInt16LE(0); _results.push(ctos_message_length = ctos_buffer.readUInt16LE(0));
} else { } else {
break; break;
} }
} else if (ctos_proto === 0) { } else if (ctos_proto === 0) {
if (ctos_buffer.length >= 3) { if (ctos_buffer.length >= 3) {
ctos_proto = ctos_buffer.readUInt8(2); _results.push(ctos_proto = ctos_buffer.readUInt8(2));
} else { } else {
break; break;
} }
...@@ -105,43 +152,40 @@ ...@@ -105,43 +152,40 @@
b = ctos_buffer.slice(3, ctos_message_length - 1 + 3); b = ctos_buffer.slice(3, ctos_message_length - 1 + 3);
if (struct = ygopro.structs[ygopro.proto_structs.CTOS[ygopro.constants.CTOS[ctos_proto]]]) { if (struct = ygopro.structs[ygopro.proto_structs.CTOS[ygopro.constants.CTOS[ctos_proto]]]) {
struct._setBuff(b); struct._setBuff(b);
setTimeout(ygopro.ctos_follows[ctos_proto].callback, 0, b, _.clone(struct.fields), client, server); ygopro.ctos_follows[ctos_proto].callback(b, _.clone(struct.fields), client, server);
} else { } else {
setTimeout(ygopro.ctos_follows[ctos_proto].callback, 0, b, null, client, server); ygopro.ctos_follows[ctos_proto].callback(b, null, client, server);
} }
} }
ctos_buffer = ctos_buffer.slice(2 + ctos_message_length); ctos_buffer = ctos_buffer.slice(2 + ctos_message_length);
ctos_message_length = 0; ctos_message_length = 0;
ctos_proto = 0; _results.push(ctos_proto = 0);
} else { } else {
break; break;
} }
} }
} }
if (!(ygopro.ctos_follows[ctos_proto] && ygopro.ctos_follows[ctos_proto].synchronous)) { return _results;
if (client.established) {
return server.write(data);
} else {
return client.pre_establish_buffers.push(data);
}
} }
}); });
stoc_buffer = new Buffer(0); stoc_buffer = new Buffer(0);
stoc_message_length = 0; stoc_message_length = 0;
stoc_proto = 0; stoc_proto = 0;
return server.on('data', function(data) { return server.on('data', function(data) {
var b, struct; var b, struct, _results;
stoc_buffer = Buffer.concat([stoc_buffer, data], stoc_buffer.length + data.length); stoc_buffer = Buffer.concat([stoc_buffer, data], stoc_buffer.length + data.length);
client.write(data);
_results = [];
while (true) { while (true) {
if (stoc_message_length === 0) { if (stoc_message_length === 0) {
if (stoc_buffer.length >= 2) { if (stoc_buffer.length >= 2) {
stoc_message_length = stoc_buffer.readUInt16LE(0); _results.push(stoc_message_length = stoc_buffer.readUInt16LE(0));
} else { } else {
break; break;
} }
} else if (stoc_proto === 0) { } else if (stoc_proto === 0) {
if (stoc_buffer.length >= 3) { if (stoc_buffer.length >= 3) {
stoc_proto = stoc_buffer.readUInt8(2); _results.push(stoc_proto = stoc_buffer.readUInt8(2));
} else { } else {
break; break;
} }
...@@ -151,23 +195,23 @@ ...@@ -151,23 +195,23 @@
b = stoc_buffer.slice(3, stoc_message_length - 1 + 3); b = stoc_buffer.slice(3, stoc_message_length - 1 + 3);
if (struct = ygopro.structs[ygopro.proto_structs.STOC[ygopro.constants.STOC[stoc_proto]]]) { if (struct = ygopro.structs[ygopro.proto_structs.STOC[ygopro.constants.STOC[stoc_proto]]]) {
struct._setBuff(b); struct._setBuff(b);
setImmediate(ygopro.stoc_follows[stoc_proto].callback, b, _.clone(struct.fields), client, server); ygopro.stoc_follows[stoc_proto].callback(b, _.clone(struct.fields), client, server);
} else { } else {
setImmediate(ygopro.stoc_follows[stoc_proto].callback, b, null, client, server); ygopro.stoc_follows[stoc_proto].callback(b, null, client, server);
} }
} }
stoc_buffer = stoc_buffer.slice(2 + stoc_message_length); stoc_buffer = stoc_buffer.slice(2 + stoc_message_length);
stoc_message_length = 0; stoc_message_length = 0;
stoc_proto = 0; _results.push(stoc_proto = 0);
} else { } else {
break; break;
} }
} }
} }
return client.write(data); return _results;
}); });
}).listen(settings.port, function() { }).listen(settings.port, function() {
return console.log("server started on " + settings.ip + ":" + settings.port); return log.info("server started", settings.ip, settings.port);
}); });
ygopro.ctos_follow('PLAYER_INFO', true, function(buffer, info, client, server) { ygopro.ctos_follow('PLAYER_INFO', true, function(buffer, info, client, server) {
...@@ -175,6 +219,7 @@ ...@@ -175,6 +219,7 @@
}); });
ygopro.ctos_follow('JOIN_GAME', false, function(buffer, info, client, server) { ygopro.ctos_follow('JOIN_GAME', false, function(buffer, info, client, server) {
var _i, _len, _ref;
if (info.version !== settings.version) { if (info.version !== settings.version) {
ygopro.stoc_send(client, 'ERROR_MSG', { ygopro.stoc_send(client, 'ERROR_MSG', {
msg: 4, msg: 4,
...@@ -188,10 +233,11 @@ ...@@ -188,10 +233,11 @@
code: 2 code: 2
}); });
return client.end(); return client.end();
} else if (info.pass === '[INCORRECT]') { } else if (!Room.validate(info.pass)) {
ygopro.stoc_send_chat(client, "房间密码不正确");
ygopro.stoc_send(client, 'ERROR_MSG', { ygopro.stoc_send(client, 'ERROR_MSG', {
msg: 1, msg: 1,
code: 1 code: 2
}); });
return client.end(); return client.end();
} else if (client.name === '[INCORRECT]') { } else if (client.name === '[INCORRECT]') {
...@@ -201,39 +247,127 @@ ...@@ -201,39 +247,127 @@
}); });
return client.end(); return client.end();
} else { } else {
log.info('join_game', info.pass, client.name);
client.room = Room.find_or_create_by_name(info.pass); client.room = Room.find_or_create_by_name(info.pass);
if (client.room.started) {
if (settings.modules.post_start_watching) {
client.is_post_watcher = true;
ygopro.stoc_send_chat_to_room(client.room, "" + client.name + " 加入了观战");
client.room.watchers.push(client);
_ref = client.room.watcher_buffers;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
buffer = _ref[_i];
client.write(buffer);
}
return ygopro.stoc_send_chat(client, "观战中.");
} else {
ygopro.stoc_send_chat(client, "决斗已开始");
ygopro.stoc_send(client, 'ERROR_MSG', {
msg: 1,
code: 2
});
return client.end();
}
} else {
return client.room.connect(client); return client.room.connect(client);
} }
}
}); });
ygopro.stoc_follow('JOIN_GAME', false, function(buffer, info, client, server) { ygopro.stoc_follow('JOIN_GAME', false, function(buffer, info, client, server) {
ygopro.stoc_send(client, 'CHAT', { var watcher;
player: 8, if (settings.modules.welcome) {
msg: "Mycard Debugging Server" ygopro.stoc_send_chat(client, settings.modules.welcome);
}
if (settings.modules.database) {
if (_.startsWith(client.room.name, 'M#')) {
User.findOne({
name: client.name
}, function(err, user) {
if (!user) {
user = new User({
name: client.name,
points: 0
});
user.save();
}
return User.count({
points: {
$gt: user.points
}
}, function(err, count) {
var rank;
rank = count + 1;
return ygopro.stoc_send_chat(client, "积分系统测试中,你现在有" + user.points + "点积分,排名" + rank + ",这些积分以后正式使用时会重置");
});
}); });
return ygopro.stoc_send(client, 'CHAT', { }
player: 8, }
msg: "这里是测试中的新服务器, 还不稳定, 随时可能崩溃, 遇到意外请淡定\n ˉˉˉˉˉ" if (settings.modules.post_start_watching && !client.room.watcher) {
client.room.watcher = watcher = net.connect(client.room.port, function() {
ygopro.ctos_send(watcher, 'PLAYER_INFO', {
name: "the Big Brother"
}); });
ygopro.ctos_send(watcher, 'JOIN_GAME', {
version: settings.version,
gameid: 2577,
some_unknown_mysterious_fucking_thing: 0,
pass: ""
});
return ygopro.ctos_send(watcher, 'HS_TOOBSERVER');
});
return watcher.on('data', function(data) {
var w, _i, _len, _ref, _results;
client.room.watcher_buffers.push(data);
_ref = client.room.watchers;
_results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
w = _ref[_i];
_results.push(w.write(data));
}
return _results;
});
}
}); });
if (settings.modules.dialogues) {
dialogues = {}; dialogues = {};
request({ request({
url: 'https://my-card.in/dialogues.json', url: settings.modules.dialogues,
json: true json: true
}, function(error, response, body) { }, function(error, response, body) {
if (_.isString(body)) { if (_.isString(body)) {
return console.log("[WARN]dialogues bad json " + body); return log.warn("dialogues bad json", body);
} else { } else {
console.log("loaded " + (_.size(body)) + " dialogues"); log.info("dialogues loaded", _.size(body));
return dialogues = body; return dialogues = body;
} }
}); });
}
ygopro.stoc_follow('GAME_MSG', false, function(buffer, info, client, server) { ygopro.stoc_follow('GAME_MSG', false, function(buffer, info, client, server) {
var card, line, msg, _i, _len, _ref, _results; var card, line, msg, playertype, pos, reason, _i, _len, _ref, _results;
msg = buffer.readInt8(0); msg = buffer.readInt8(0);
if (ygopro.constants.MSG[msg] === 'START') {
playertype = buffer.readUInt8(1);
client.is_first = !(playertype & 0xf);
}
if (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;
}
reason = buffer.readUInt8(2);
log.info({
winner: pos,
reason: reason
});
client.room.duels.push({
winner: pos,
reason: reason
});
}
if (settings.modules.dialogues) {
if (ygopro.constants.MSG[msg] === 'SUMMONING' || ygopro.constants.MSG[msg] === 'SPSUMMONING') { if (ygopro.constants.MSG[msg] === 'SUMMONING' || ygopro.constants.MSG[msg] === 'SPSUMMONING') {
card = buffer.readUInt32LE(1); card = buffer.readUInt32LE(1);
if (dialogues[card]) { if (dialogues[card]) {
...@@ -246,108 +380,301 @@ ...@@ -246,108 +380,301 @@
return _results; return _results;
} }
} }
}
}); });
/* /*
if ygopro.constants.MSG[msg] == 'WIN' #房间管理
room = Room.find_by_client(client) ygopro.stoc_follow 'HS_PLAYER_ENTER', false, (buffer, info, client, server)->
if !room #console.log "PLAYER_ENTER to #{client.name}: #{info.name}, #{info.pos}"
console.log "[WARN]win: can't find room by player #{client.player}" #room = client.room
return #if !room
if _.startsWith(room.name, 'M#') and room.dueling # console.log "[WARN]player_enter: can't find room by player #{client.player}"
room.dueling = false # return
#room.pos_name[info.pos] = info.name
loser_name = room.pos_name[buffer.readUInt8(1)]
winner_name = room.pos_name[1 - buffer.readUInt8(1)] ygopro.stoc_follow 'HS_PLAYER_CHANGE', false, (buffer, info, client, server)->
#type = buffer.readUInt8(2) #client.ready = info.status & 0xF != 0
User.findOne { name: winner_name }, (err, winner)-> #client.pos = info.status >> 4
if(err) #console.log "PLAYER_CHANGE to #{client.name}: #{info.status & 0xF != 0}, #{info.status >> 4}"
console.log "#{err} when finding user #{winner_name}"
else if(!winner)
console.log "user #{winner_name} not exist"
else
User.findOne { name: loser_name }, (err, loser)->
if(err)
console.log "#{err} when finding user #{loser_name}"
else if(!loser)
console.log "user #{loser_name} not exist"
else
winner.points += 10
loser.points -= 5
winner.save()
loser.save()
console.log "#{winner} 增加10点积分,现在有#{winner.points}点"
console.log "#{loser} 减少5点积分,现在有#{loser.points}点"
#mongoose = require 'mongoose'
#mongoose.connect('mongodb://localhost/mycard');
#User = mongoose.model 'User',
# name: String
# points: Number
#ygopro.stoc_follow 'HS_PLAYER_CHANGE', false, (buffer, info, client, server)->
# console.log 'HS_PLAYER_CHANGE', info
*/ */
ygopro.stoc_follow('HS_PLAYER_ENTER', false, function(buffer, info, client, server) {
return console.log("PLAYER_ENTER to " + client.name + ": " + info.name + ", " + info.pos);
});
ygopro.stoc_follow('HS_PLAYER_CHANGE', false, function(buffer, info, client, server) {
return console.log("PLAYER_CHANGE to " + client.name + ": " + (info.status & 0xF !== 0) + ", " + (info.status >> 4));
});
ygopro.stoc_follow('TYPE_CHANGE', false, function(buffer, info, client, server) { ygopro.stoc_follow('TYPE_CHANGE', false, function(buffer, info, client, server) {
var is_host, selftype; var is_host, selftype;
selftype = info.type & 0xf; selftype = info.type & 0xf;
is_host = ((info.type >> 4) & 0xf) !== 0; is_host = ((info.type >> 4) & 0xf) !== 0;
client.is_host = is_host; client.is_host = is_host;
client.pos = selftype; return client.pos = selftype;
return console.log("TYPE_CHANGE to " + client.name + ":", info, selftype, is_host); });
ygopro.stoc_send_random_tip = function(client) {
if (tips) {
return ygopro.stoc_send_chat(client, "Tip: " + tips[Math.floor(Math.random() * tips.length)]);
}
};
tips = null;
request({
url: settings.modules.tips,
json: true
}, function(error, response, body) {
tips = body;
return log.info("tips loaded", tips.length);
});
ygopro.stoc_follow('DUEL_START', false, function(buffer, info, client, server) {
var player, _i, _len, _ref;
if (!client.room.started) {
client.room.started = true;
client.room.duels = [];
client.room.dueling_players = [];
_ref = client.room.players;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
player = _ref[_i];
if (!(player.pos !== 7)) {
continue;
}
client.room.dueling_players[player.pos] = player;
player.deck = mycard.load_card_usages_from_cards(player.main, player.side);
}
if (!client.room.dueling_players[0] || !client.room.dueling_players[1]) {
log.error('incomplete room', client.room.dueling_players, client.room.players);
}
}
if (settings.modules.tips) {
return ygopro.stoc_send_random_tip(client);
}
});
ygopro.ctos_follow('CHAT', false, function(buffer, info, client, server) {
switch (_.trim(info.msg)) {
case '/ping':
return execFile('ss', ['-it', "dst " + client.remoteAddress + ":" + client.remotePort], function(error, stdout, stderr) {
var line;
if (error) {
return ygopro.stoc_send_chat_to_room(client.room, error);
} else {
line = _.lines(stdout)[2];
if (line.indexOf('rtt') !== -1) {
return ygopro.stoc_send_chat_to_room(client.room, line);
} else {
log.warn('ping', stdout);
return ygopro.stoc_send_chat_to_room(client.room, stdout);
}
}
});
case '/ranktop':
if (settings.modules.database) {
return User.find(null, null, {
sort: {
points: -1
},
limit: 8
}, function(err, users) {
var index, user, _results;
if (err) {
return log.error('ranktop', err);
}
_results = [];
for (index in users) {
user = users[index];
_results.push(ygopro.stoc_send_chat(client, [parseInt(index) + 1, user.points, user.name].join(' ')));
}
return _results;
});
}
break;
case '/help':
ygopro.stoc_send_chat(client, "Mycard MatchServer 指令帮助");
ygopro.stoc_send_chat(client, "/help 显示这个帮助信息");
if (settings.modules.tips) {
ygopro.stoc_send_chat(client, "/tip 显示一条提示");
}
return ygopro.stoc_send_chat(client, "/senddeck 发送自己的卡组");
case '/tip':
if (settings.modules.tips) {
return ygopro.stoc_send_random_tip(client);
}
break;
case '/senddeck':
if (client.deck != null) {
ygopro.stoc_send_chat(client, "正在读取卡组信息... ");
return mycard.deck_url_short(client.name, client.deck, function(url) {
return ygopro.stoc_send_chat_to_room(client.room, "卡组链接: " + url);
});
} else {
return ygopro.stoc_send_chat_to_room(client.room, "读取卡组信息失败");
}
break;
case '/admin showroom':
return log.info(client.room);
}
});
ygopro.ctos_follow('UPDATE_DECK', false, function(buffer, info, client, server) {
var i, main, side;
log.info(info);
main = (function() {
var _i, _ref, _results;
_results = [];
for (i = _i = 0, _ref = info.mainc; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
_results.push(info.deckbuf[i]);
}
return _results;
})();
side = (function() {
var _i, _ref, _ref1, _results;
_results = [];
for (i = _i = _ref = info.mainc, _ref1 = info.mainc + info.sidec; _ref <= _ref1 ? _i < _ref1 : _i > _ref1; i = _ref <= _ref1 ? ++_i : --_i) {
_results.push(info.deckbuf[i]);
}
return _results;
})();
client.main = main;
return client.side = side;
}); });
if (settings.modules.skip_empty_side) {
ygopro.stoc_follow('CHANGE_SIDE', false, function(buffer, info, client, server) {
if (!_.any(client.deck, function(card_usage) {
return card_usage.side;
})) {
ygopro.ctos_send(server, 'UPDATE_DECK', {
mainc: client.main.length,
sidec: 0,
deckbuf: client.main
});
return ygopro.stoc_send_chat(client, '等待更换副卡组中...');
}
});
}
/*
# 开包大战
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
ygopro.ctos_follow 'UPDATE_DECK', false, (buffer, info, client, server)->
ygopro.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)]
ygopro.ctos_send server, 'UPDATE_DECK', {
mainc: deck.length,
sidec: 0,
deckbuf: deck
}
ygopro.ctos_send server, 'HS_READY'
*/
if (settings.modules.http) {
level_points = require('./level_points.json');
waiting = [[]];
for (i in level_points) {
waiting.push([]);
}
log.info('level_points loaded', level_points);
http.createServer(function(request, response) { http.createServer(function(request, response) {
var player, room; var level, name, password, player, room, _ref, _ref1;
url = url.parse(request.url); url = url.parse(request.url);
if (url.pathname === '/count.json') { if (url.pathname === '/count.json') {
response.writeHead(200); response.writeHead(200);
response.end(Room.all.length.toString()); return response.end(Room.all.length.toString());
} else if (url.pathname === '/match') {
if (request.headers['authorization']) {
_ref1 = new Buffer((_ref = request.headers['authorization'].split(/\s+/).pop()) != null ? _ref : '', 'base64').toString().split(':'), name = _ref1[0], password = _ref1[1];
return User.findOne({
name: name
}, function(err, user) {
var index, level, points;
if (!user) {
user = new User({
name: name,
points: 0,
elo: 1400
});
user.save();
}
level = level_points.length;
for (index in level_points) {
points = level_points[index];
if (user.points < points) {
level = index;
break;
}
}
response.allowance = 0;
waiting[level].push(response);
return request.on('close', function() {
index = waiting[level].indexOf(response);
if (index !== -1) {
return waiting[level].splice(index, 1);
}
});
});
} else {
level = 1;
response.allowance = 0;
waiting[level].push(response);
return request.on('close', function() {
var index;
index = waiting[level].indexOf(response);
if (index !== -1) {
return waiting[level].splice(index, 1);
}
});
}
} else if (url.pathname === '/rooms.json') { } else if (url.pathname === '/rooms.json') {
response.writeHead(404); response.writeHead(404);
response.end(); return response.end();
} } else if (url.query === 'operation=getroomjson') {
if (url.query === 'operation=getroomjson') {
response.writeHead(200); response.writeHead(200);
return response.end(JSON.stringify({ return response.end(JSON.stringify({
rooms: (function() { rooms: (function() {
var _i, _len, _ref, _results; var _i, _len, _ref2, _results;
_ref = Room.all; _ref2 = Room.all;
_results = []; _results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) { for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
room = _ref[_i]; room = _ref2[_i];
if (room.established) {
_results.push({ _results.push({
roomid: room.port.toString(), roomid: room.port.toString(),
roomname: room.name, roomname: room.name.split('$', 2)[0],
needpass: false.toString(), needpass: (room.name.indexOf('$') !== -1).toString(),
users: (function() { users: (function() {
var _j, _len1, _ref1, _results1; var _j, _len1, _ref3, _results1;
_ref1 = room.players; _ref3 = room.players;
_results1 = []; _results1 = [];
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { for (_j = 0, _len1 = _ref3.length; _j < _len1; _j++) {
player = _ref1[_j]; player = _ref3[_j];
if (player.pos != null) {
_results1.push({ _results1.push({
id: (-1).toString(), id: (-1).toString(),
name: player.name, name: player.name,
pos: player.pos pos: player.pos
}); });
} }
}
return _results1; return _results1;
})(), })(),
istart: "wait" istart: room.started ? "start" : "wait"
}); });
} }
}
return _results; return _results;
})() })()
})); }));
...@@ -355,7 +682,71 @@ ...@@ -355,7 +682,71 @@
response.writeHead(404); response.writeHead(404);
return response.end(); return response.end();
} }
}).listen(settings.http_port); }).listen(settings.modules.http.port);
setInterval(function() {
var displacement, headers, index, level, opponent, opponent_level, player, room, _i, _ref, _results;
_results = [];
for (level = _i = _ref = level_points.length; _ref <= 0 ? _i <= 0 : _i >= 0; level = _ref <= 0 ? ++_i : --_i) {
_results.push((function() {
var _j, _ref1, _ref2, _results1;
_ref1 = waiting[level];
_results1 = [];
for (index in _ref1) {
player = _ref1[index];
opponent_level = null;
opponent = _.find(waiting[level], function(opponent) {
log.info(opponent, player);
return opponent !== player;
});
log.info('--------1--------', waiting, opponent);
if (opponent) {
opponent_level = level;
} else if (player.allowance > 0) {
for (displacement = _j = 1, _ref2 = player.allowance; 1 <= _ref2 ? _j <= _ref2 : _j >= _ref2; displacement = 1 <= _ref2 ? ++_j : --_j) {
if (level + displacement <= level_points.length) {
opponent = waiting[level + displacement][0];
if (opponent) {
opponent_level = level + displacement;
break;
}
}
if (level - displacement >= 0) {
opponent = waiting[level - displacement][0];
if (opponent) {
opponent_level = level - displacement;
break;
}
}
}
}
if (opponent) {
if (waiting[level].indexOf(player) === -1 || waiting[opponent_level].indexOf(opponent) === -1) {
log.info(waiting, player, level, opponent, opponent_level);
throw 'WTF';
}
waiting[level].splice(waiting[level].indexOf(player), 1);
waiting[opponent_level].splice(waiting[opponent_level].indexOf(opponent), 1);
index--;
room = "mycard://" + settings.ip + ":" + settings.port + "/M#" + (_.uniqueId()) + "$" + (_.random(999));
log.info('matched', room);
headers = {
"Access-Control-Allow-Origin": "*",
"Content-Type": "text/plain"
};
player.writeHead(200, headers);
player.end(room);
opponent.writeHead(200, headers);
_results1.push(opponent.end(room));
} else {
_results1.push(player.allowance++);
}
}
return _results1;
})());
}
return _results;
}, 2000);
}
inotify = new Inotify(); inotify = new Inotify();
...@@ -378,7 +769,7 @@ ...@@ -378,7 +769,7 @@
} }
} }
} else { } else {
return console.log('[warn] event without filename'); return log.error("event without filename");
} }
} }
}); });
...@@ -392,7 +783,7 @@ ...@@ -392,7 +783,7 @@
if (room.alive) { if (room.alive) {
_results.push(room.alive = false); _results.push(room.alive = false);
} else { } else {
console.log("kill room " + room.port); log.info("kill room", room.port);
_ref1 = room.players; _ref1 = room.players;
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
player = _ref1[_j]; player = _ref1[_j];
...@@ -406,88 +797,8 @@ ...@@ -406,88 +797,8 @@
return _results; return _results;
}, 900000); }, 900000);
ygopro.stoc_send_tip = function(client, tip) {
var line, lines, _i, _len, _ref, _results;
lines = _.lines(tip);
ygopro.stoc_send_chat(client, "Tip: " + lines[0]);
_ref = lines.slice(1);
_results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
line = _ref[_i];
_results.push(ygopro.stoc_send_chat(client, line));
}
return _results;
};
ygopro.stoc_send_random_tip = function(client) {
if (tips) {
return ygopro.stoc_send_tip(client, tips[Math.floor(Math.random() * tips.length)]);
}
};
tips = null;
request({
url: 'https://my-card.in/tips.json',
json: true
}, function(error, response, body) {
tips = body;
return console.log("loaded " + tips.length + " tips");
});
ygopro.stoc_follow('DUEL_START', false, function(buffer, info, client, server) {
return ygopro.stoc_send_random_tip(client);
/*
room = Room.find_by_client(client)
if !room
console.log "[WARN]duel start: can't find room by player #{client.player}"
return
room.dueling = true
if _.startsWith(room.name, 'M#')
User.findOne { name: client.player }, (err, user)->
if !user
user = new User({name: client.player, points: 0})
user.save()
ygopro.stoc_send_chat(client, "积分系统测试中,你现在有#{user.points}点积分,这些积分以后可能会重置")
*/
});
ygopro.ctos_follow('CHAT', false, function(buffer, info, client, server) {
if (_.trim(info.msg) === '/tip') {
return ygopro.stoc_send_random_tip(client);
}
});
/*
# 开包大战
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
ygopro.ctos_follow 'UPDATE_DECK', false, (buffer, info, client, server)->
ygopro.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)]
ygopro.ctos_send server, 'UPDATE_DECK', {
mainc: deck.length,
sidec: 0,
deckbuf: deck
}
ygopro.ctos_send server, 'HS_READY'
*/
}).call(this); }).call(this);
/*
//@ sourceMappingURL=ygopro-server.map
*/
...@@ -6,5 +6,5 @@ ...@@ -6,5 +6,5 @@
"ygopro-server.coffee" "ygopro-server.coffee"
], ],
"names": [], "names": [],
"mappings": ";AACA;CAAA,KAAA,gGAAA;;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,CAOA,CAAI,IAAA,KAAA;;CAPJ,CAQA,CAAA,IAAQ,YAAA;;CARR,CASA,CAAa,EAAb,EAAQ;;CATR,CAWA,CAAU,IAAV,EAAU;;CAXV,CAYA,CAAU,IAAV,EAAU;;CAZV,CAeA,CAAS,GAAT,CAAS,MAAA;;CAfT,CAgBA,CAAO,CAAP,GAAO,IAAA;;CAhBP,CAmBA,CAAW,IAAA,CAAX,OAAW;;CAnBX,CAsBA,CAAQ,EAAR;;CACA,CAAA,EAAG,CAAmB,EAAZ,EAAV;AACE,CAAA,CAAA,EAAA,IAAQ;AACR,CADA,CAAA,EACA,IAAQ,CAAR;IAzBF;;CAAA,CA4BA,CAAG,GAAc,GAAC,GAAlB;CACE,OAAA,0FAAA;CAAA,EAAa,CAAb,EAAA;CAAA,EACgB,CAAhB,EAAM;CADN,CAIA,CAAmB,CAAnB,EAAM,CAAN,EAAoB;CAClB,EAAA,GAAA,CAAO,EAAP,OAAa;AACN,CAAP,GAAA,EAAA;CACE,GAAkC,EAAM,EAAxC;CAAA,GAAW,EAAL,IAAN;UAAA;CAAA,EACgB,CADhB,EACM,EAAN;QAHF;CAIO,EAAP,GAAM,OAAN;CALF,IAAmB;CAJnB,CAWA,CAAmB,CAAnB,CAAmB,CAAb,CAAN,EAAoB;CAClB,EAAA,EAAA,CAAA,CAAO,QAAM;AACN,CAAP,GAAA,EAAA;CACE,GAAyC,EAAM,EAA/C;CAAA,CAA+B,EAApB,CAAX,CAAM,IAAN;UAAA;CAAA,EACgB,EADhB,CACM,EAAN;QAHF;CAIO,EAAP,GAAM,OAAN;CALF,IAAmB;CAXnB,CAkBA,CAAmB,CAAnB,EAAM,CAAN,EAAoB;CAClB,EAAA,GAAA,CAAO,EAAP,OAAa;AACe,CAA5B,GAAA,EAAA;CAAA,EAAgB,CAAhB,EAAM,EAAN;QADA;AAEO,CAAP,GAAA,EAAA;CACE,CAA8B,IAAxB,EAAN,EAAA,IAAA;CAAA,EACgB,CADhB,EACM,EAAN;CACO,EAAP,GAAM,SAAN;QANe;CAAnB,IAAmB;CAlBnB,CA0BA,CAAmB,CAAnB,CAAmB,CAAb,CAAN,EAAoB;CAClB,EAAA,EAAA,CAAA,CAAO,QAAM;CAAb,EACgB,EADhB,CACA;AACO,CAAP,GAAA,EAAA;CACE,CAA+B,CAAQ,EAAvC,CAAM,EAAN,CAA+B,KAA/B;CAAA,EACgB,CADhB,EACM,EAAN;CACO,EAAP,GAAM,SAAN;QANe;CAAnB,IAAmB;CA1BnB,EAoCkB,CAAlB,EAAkB,KAAlB;CApCA,EAqCsB,CAAtB,eAAA;CArCA,EAsCa,CAAb,MAAA;CAtCA,EAwCmC,CAAnC,CAAmC,CAA7B,eAAN;CAxCA,CA0CA,CAAkB,CAAlB,EAAM,GAAa;CACjB,QAAA,CAAA;CAAA,CAA0C,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,GAAG,EAAM,IAAc,EAAvB;CACE,CAAyB,CAArB,EAAA,MAAW,GAAf,KAAyB;CACzB,EAAY,CAAT,EAAA,CAAwB,EAA0C,CAAM,GAA5B,CAA/C;CACE,KAAM,EAAN,QAAA;CAAA,CACqD,GAAM,CAA1C,EAAjB,EAAA,EAA+B,IAA/B;MAFF,UAAA;CAIE,CAAqD,EAArD,EAAiB,EAAjB,EAAA,EAA+B,IAA/B;gBANJ;cAAA;CAAA,EAQc,EAAA,MAAd,CAAA,OAAc;CARd,EASsB,SAAtB,OAAA;CATA,EAUa,OAAb,EAAA;MAXF,MAAA;CAaE,iBAbF;YAXF;UADF;CAFA,MAEA;AA2BA,CAAA,GAAA,EAAA,IAA2B,CAA3B,CAA2B;CACzB,GAAG,EAAM,EAAT,GAAA;CACS,GAAP,CAAA,CAAM,WAAN;MADF,IAAA;CAGS,GAAP,EAAM,WAAN,IAA4B;UAJhC;QA9BgB;CAAlB,IAAkB;CA1ClB,EA+EkB,CAAlB,EAAkB,KAAlB;CA/EA,EAgFsB,CAAtB,eAAA;CAhFA,EAiFa,CAAb,MAAA;CAEO,CAAP,CAAkB,CAAA,EAAZ,GAAa,EAAnB;CACE,QAAA,CAAA;CAAA,CAA0C,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,GAAG,EAAM,IAAc,EAAvB;CACE,CAAyB,CAArB,EAAA,MAAW,GAAf,KAAyB;CACzB,EAAY,CAAT,EAAA,CAAwB,EAA0C,CAAM,GAA5B,CAA/C;CACE,KAAM,EAAN,QAAA;CAAA,CACuD,GAAG,CAAvC,EAAnB,EAAiC,EAAjC,IAAA;MAFF,UAAA;CAIE,CAAuD,EAAvD,EAAmB,EAAnB,EAAiC,EAAjC,IAAA;gBANJ;cAAA;CAAA,EAQc,EAAA,MAAd,CAAA,OAAc;CARd,EASsB,SAAtB,OAAA;CATA,EAUa,OAAb,EAAA;MAXF,MAAA;CAaE,iBAbF;YAXF;UADF;CAFA,MAEA;CA4BO,GAAP,CAAA,CAAM,OAAN;CA/BF,IAAkB;CApFpB,CAqHuB,CArHN,CAAjB,EAAA,EAqHgB,CAAO;CACb,CAAK,CAAb,CAAA,GAAO,CAAiC,GAAxC,SAAa;CAtHf,EAqHuB;;CAjJvB,CAsJA,CAAwC,CAAxC,EAAM,GAAmC,EAAzC,EAAA;CACS,EAAO,CAAd,EAAM,KAAN;CADF,EAAwC;;CAtJxC,CAyJA,CAAuC,CAAA,CAAvC,CAAM,GAAkC,EAAxC;CACE,GAAA,CAAmB,EAAhB,CAAwB;CACzB,CAAyB,IAAzB,GAAA,EAAA;CAAqC,CAC9B,CAAL,KAAA;CADmC,CAE7B,EAAN,GAFmC,CAEnC;CAFF,OAAA;CAIO,EAAP,GAAM,OAAN;AACO,CAAD,GAAA,EANR;CAOE,CAA6B,IAA7B,OAAA,CAAA;CAAA,CACyB,IAAzB,GAAA,EAAA;CAAqC,CAC9B,CAAL,KAAA;CADmC,CAE7B,EAAN,IAAA;CAHF,OACA;CAIO,EAAP,GAAM,OAAN;CACW,GAAL,CAAa,CAbrB,OAAA;CAcE,CAAyB,IAAzB,GAAA,EAAA;CAAqC,CAC9B,CAAL,KAAA;CADmC,CAE7B,EAAN,IAAA;CAFF,OAAA;CAIO,EAAP,GAAM,OAAN;CACa,GAAP,CAAe,CAnBvB,OAAA;CAoBE,CAAyB,IAAzB,GAAA,EAAA;CAAqC,CAC9B,CAAL,KAAA;CADmC,CAE7B,EAAN,IAAA;CAFF,OAAA;CAIO,EAAP,GAAM,OAAN;MAxBF;CA0BE,EAAc,CAAd,EAAA,gBAAc;CACP,GAAI,EAAL,CAAN,MAAA;MA5BmC;CAAvC,EAAuC;;CAzJvC,CA0LA,CAAuC,CAAA,CAAvC,CAAM,GAAkC,EAAxC;CACE,CAAyB,EAAzB,EAAM,GAAN;CAAiC,CACvB,IAAR;CAD+B,CAE1B,CAAL,GAAA,mBAF+B;CAAjC,KAAA;CAIO,CAAkB,IAAnB,GAAN,EAAA;CAAiC,CACvB,IAAR;CAD+B,CAE1B,CAAL,GAAA,gEAF+B;CALI,KAKrC;CALF,EAAuC;;CA1LvC,CAqMA,CAAY,MAAZ;;CArMA,CAsMA,KAAA;CACE,CAAK,CAAL,CAAA,+BAAA;CAAA,CACM,EAAN;EACE,CAAA,CAHJ,CAGI,GAAA,CAAC;CACD,GAAA,IAAG;CACO,EAAR,CAAA,GAAO,MAAP,cAAa;MADf;CAGE,EAAA,CAAqB,EAArB,CAAO,EAAM,GAAb;CAHF,EAIc,MAAZ,IAAA;MALF;CAHJ,EAGI;;CAzMJ,CAgNA,CAAsC,CAAA,CAAtC,CAAM,GAAiC,CAAvC,CAAA;CACE,OAAA,iCAAA;CAAA,EAAA,CAAA,EAAY,EAAN;CACN,EAAwB,CAAxB,CAAgC,CAAvB,GAAU,EAAhB,EAAH;CACE,EAAO,CAAP,EAAA,MAAO;CACP,GAAG,EAAH,GAAa;CACX;CAAA;cAAA,6BAAA;2BAAA;CACE,CAA8B,EAA9B,EAAM,QAAN;CADF;yBADF;QAFF;MAFoC;CAAtC,EAAsC;;CAStC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAzNA;;CAAA,CAqQA,CAA6C,CAAA,CAA7C,CAAM,GAAwC,EAA9C,MAAA;CACU,EAAR,CAAa,EAAuB,CAA7B,IAAP,OAAa;CADf,EAA6C;;CArQ7C,CA6QA,CAA8C,CAAA,CAA9C,CAAM,GAAyC,EAA/C,OAAA;CAGU,EAAR,CAAa,CAAuD,CAA/B,CAA9B,IAAP,QAAa;CAHf,EAA8C;;CA7Q9C,CAkRA,CAAyC,CAAA,CAAzC,CAAM,GAAoC,EAA1C,EAAA;CACE,OAAA,SAAA;CAAA,EAAW,CAAX,IAAA;CAAA,EACU,CAAV,CAAsC,EAAtC;CADA,EAEiB,CAAjB,EAAM,CAAN;CAFA,EAGA,CAAA,EAAM,EAHN;CAIQ,CAAsC,CAA9C,CAAa,EAAsB,CAA5B,CAAP,GAAA,MAAa;CALf,EAAyC;;CAlRzC,CA0RA,CAAkB,CAAd,GAAc,CAAA,CAAC,GAAnB;CAEE,OAAA,IAAA;CAAA,EAAA,CAAA,CAAM,EAAiB;CACvB,EAAM,CAAN,CAAmB,GAAhB,KAAH;CACE,EAAA,GAAA,EAAQ,CAAR;CAAA,EACA,CAAiB,EAAjB,EAAQ;CACE,EAAD,CAAH,CAAgB,CAHxB,EAGQ,KAHR;CAIE,EAAA,GAAA,EAAQ,CAAR;CAAA,EACA,GAAA,EAAQ;MANV;CAOA,EAAM,CAAN,CAAG,kBAAH;CACE,EAAA,GAAA,EAAQ,CAAR;CACS,EAAT,CAAiB,IAAT,CAAK,IAAb;CAA4B,IAAA,GAAA;;CAAQ;CAAA;gBAAA,2BAAA;6BAAA;CAClC;CAAA,CAAQ,EAAI,EAAZ,EAAQ,MAAR;CAAA,CACU,EAAI,IAAd,MAAA;CADA,CAEU,GAAK,GAAf,MAAA;CAFA,IAGA,SAAA;;CAAQ;CAAA;sBAAA,wBAAA;sCAAA;CACN;AAAM,CAAN,CAAA,MAAI,YAAJ;CAAA,CACM,EAAN,EAAY,cAAZ;CADA,CAEK,CAAL,GAAW,cAAX;CAFA;CADM;;CAHR;CAAA,CAQQ,IAAR,QAAA;CARA;CADkC;;CAAR;CAA5B,OAAa;MAFf;CAcE,EAAA,GAAA,EAAQ,CAAR;CACS,EAAT,KAAQ,KAAR;MAxBc;CAAlB,EAAkB,GAAlB,EAyBgB,CAzBhB;;CA1RA,CAsTA,CAAc,CAAA,GAAd;;CAtTA,CAuTA,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;CA1TZ,GAuTA;;CAvTA,CAwUA,CAAY,MAAA,EAAZ;CACE,OAAA,gDAAA;CAAA;CAAA;UAAA,iCAAA;uBAAA;CACE,GAAG,CAAH,CAAA;CACE,EAAa,CAAT,CAAJ;MADF,EAAA;CAGE,EAAA,CAA4B,GAArB,CAAP,IAAa;CACb;CAAA,YAAA,iCAAA;8BAAA;AACuD,CAArD,GAAA,EAA2D,IAA3D;CAAA,CAA8B,IAAxB,MAAN,EAAA;YADF;CAAA,QADA;CAAA,GAGI,GAAQ;QAPhB;CAAA;qBADU;CAAZ,CASE,CATU,GAAZ;;CAxUA,CAoVA,CAAuB,GAAjB,GAAkB,IAAxB;CACE,OAAA,6BAAA;CAAA,EAAQ,CAAR,CAAA;CAAA,CAC+B,CAAM,CAArC,CAA2C,CAArC,CAAyB,OAA/B;CACA;CAAA;UAAA,iCAAA;uBAAA;CACE,CAA8B,EAA9B,EAAM,QAAN;CADF;qBAHqB;CApVvB,EAoVuB;;CApVvB,CA0VA,CAA8B,GAAxB,GAAyB,WAA/B;CACE,GAAA;CAAO,CAAsB,CAAgC,CAA3B,CAAA,CAA5B,OAAN;MAD4B;CA1V9B,EA0V8B;;CA1V9B,CA6VA,CAAO,CAAP;;CA7VA,CA8VA,KAAA;CACE,CAAK,CAAL,CAAA,0BAAA;CAAA,CACM,EAAN;EACE,CAAA,CAHJ,CAGI,GAAA,CAAC;CACD,EAAO,CAAP;CACQ,EAAR,CAAyB,EAAZ,CAAN,EAAM,EAAb;CALJ,EAGI;;CAjWJ,CAqWA,CAAwC,CAAA,CAAxC,CAAM,GAAmC,EAAzC,CAAA;CACS,KAAD,KAAN,SAAA;CAEA;;;;;;;;;;;;;;CAHsC;CAAxC,EAAwC;;CArWxC,CAsXA,CAAkC,CAAA,CAAlC,CAAM,GAA6B,EAAnC;CACE,EAAG,CAAH,CAAuB,CAAvB;CACS,KAAD,OAAN,OAAA;MAF8B;CAAlC,EAAkC;;CAIlC;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA1XA;CAAA" "mappings": "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"
} }
\ No newline at end of file
_ = require 'underscore'
_.str = require 'underscore.string'
_.mixin(_.str.exports());
Struct = require('struct').Struct Struct = require('struct').Struct
#常量/类型声明 #常量/类型声明
...@@ -102,7 +106,14 @@ for name, declaration of structs_declaration ...@@ -102,7 +106,14 @@ for name, declaration of structs_declaration
#util #util
@stoc_send_chat = (client, msg, player = 8)-> @stoc_send_chat = (client, msg, player = 8)->
for line in _.lines(msg)
@stoc_send client, 'CHAT', { @stoc_send client, 'CHAT', {
player: player player: player
msg: msg msg: line
} }
@stoc_send_chat_to_room = (room, msg, player = 8)->
for client in room.players
@stoc_send_chat(client, msg, player) if client
for client in room.watchers
@stoc_send_chat(client, msg, player) if client
// Generated by CoffeeScript 1.6.3 // Generated by CoffeeScript 1.6.3
(function() { (function() {
var Struct, declaration, field, name, result, structs_declaration, type, typedefs, _i, _len; var Struct, declaration, field, name, result, structs_declaration, type, typedefs, _, _i, _len;
_ = require('underscore');
_.str = require('underscore.string');
_.mixin(_.str.exports());
Struct = require('struct').Struct; Struct = require('struct').Struct;
...@@ -161,13 +167,45 @@ ...@@ -161,13 +167,45 @@
}; };
this.stoc_send_chat = function(client, msg, player) { this.stoc_send_chat = function(client, msg, player) {
var line, _j, _len1, _ref, _results;
if (player == null) { if (player == null) {
player = 8; player = 8;
} }
return this.stoc_send(client, 'CHAT', { _ref = _.lines(msg);
_results = [];
for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) {
line = _ref[_j];
_results.push(this.stoc_send(client, 'CHAT', {
player: player, player: player,
msg: msg msg: line
}); }));
}
return _results;
};
this.stoc_send_chat_to_room = function(room, msg, player) {
var client, _j, _k, _len1, _len2, _ref, _ref1, _results;
if (player == null) {
player = 8;
}
_ref = room.players;
for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) {
client = _ref[_j];
if (client) {
this.stoc_send_chat(client, msg, player);
}
}
_ref1 = room.watchers;
_results = [];
for (_k = 0, _len2 = _ref1.length; _k < _len2; _k++) {
client = _ref1[_k];
if (client) {
_results.push(this.stoc_send_chat(client, msg, player));
} else {
_results.push(void 0);
}
}
return _results;
}; };
}).call(this); }).call(this);
......
...@@ -6,5 +6,5 @@ ...@@ -6,5 +6,5 @@
"ygopro.coffee" "ygopro.coffee"
], ],
"names": [], "names": [],
"mappings": "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" "mappings": "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"
} }
\ 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