Commit 1cd3c81c authored by zh99998's avatar zh99998

ruby193

parent 096e2478
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
require 'rubygems' require 'rubygems'
require 'rake' require 'rake'
require 'rake/clean' require 'rake/clean'
require 'rake/gempackagetask' require 'rubygems/package_task'
require 'rake/rdoctask' require 'rdoc/task'
#require 'rake/testtask' #require 'rake/testtask'
Windows = RUBY_PLATFORM["mingw"] || RUBY_PLATFORM["mswin"] Windows = RUBY_PLATFORM["mingw"] || RUBY_PLATFORM["mswin"]
...@@ -43,7 +43,7 @@ spec = Gem::Specification.new do |s| ...@@ -43,7 +43,7 @@ spec = Gem::Specification.new do |s|
#s.bindir = "bin" #s.bindir = "bin"
end end
Rake::GemPackageTask.new(spec) do |p| Gem::PackageTask.new(spec) do |p|
p.gem_spec = spec p.gem_spec = spec
if Windows if Windows
p.need_zip = true p.need_zip = true
......
This diff was suppressed by a .gitattributes entry.
...@@ -92,7 +92,7 @@ class Action ...@@ -92,7 +92,7 @@ class Action
end end
end end
def run def run
$log.debug('移动操作执行'){self.inspect} $log.info('移动操作执行'){self.inspect}
from_field = parse_field(@from_pos) from_field = parse_field(@from_pos)
......
...@@ -5,7 +5,7 @@ class Game_Card ...@@ -5,7 +5,7 @@ class Game_Card
@@count = 0 @@count = 0
def initialize(card=nil) def initialize(card=nil)
@@count += 1 @@count += 1
$log.info "创建活动卡片<#{card ? card.name : '??'}>,共计#{@@count}张" $log.debug "创建活动卡片<#{card ? card.name : '??'}>,共计#{@@count}张"
@card = card || Card.find(nil) @card = card || Card.find(nil)
reset reset
end end
......
...@@ -140,8 +140,7 @@ class Game_Event ...@@ -140,8 +140,7 @@ class Game_Event
@title = title @title = title
@message = message @message = message
@fatal = fatal @fatal = fatal
$log.error(@fatal ? "致命错误" : "一般错误"){"#{@title}: #{@message}"} $log.error(@fatal ? "致命错误" : "一般错误"){"#{@title}: #{@message} #{caller}"}
$log.debug caller
end end
end end
class Unknown < Error class Unknown < Error
......
...@@ -62,7 +62,7 @@ class Replay ...@@ -62,7 +62,7 @@ class Replay
action = Action.parse action_str action = Action.parse action_str
action.from_player = from_players.next action.from_player = from_players.next
Game_Event::Action.new(action, action_str) Game_Event::Action.new(action, action_str)
end end
$game.room = result.room = Room.new(0, "Replay", result.player1, result.player2) $game.room = result.room = Room.new(0, "Replay", result.player1, result.player2)
result result
end end
......
...@@ -24,7 +24,7 @@ class Window_Login ...@@ -24,7 +24,7 @@ class Window_Login
$game.user = User.new(0) $game.user = User.new(0)
Widget_Msgbox.new("回放战报", "战报读取中...") Widget_Msgbox.new("回放战报", "战报读取中...")
$scene.draw $scene.draw
$log.debug('iduel window_login'){'loading reply file'} $log.info('iduel window_login'){'loading reply file'}
$scene = Scene_Replay.new Replay.load file $scene = Scene_Replay.new Replay.load file
end end
@last_clicked = Time.now @last_clicked = Time.now
......
...@@ -15,7 +15,7 @@ begin ...@@ -15,7 +15,7 @@ begin
def save_config(file="config.yml") def save_config(file="config.yml")
File.open(file,"w"){|file| YAML.dump($config, file)} File.open(file,"w"){|file| YAML.dump($config, file)}
end end
Thread.abort_on_exception = true
require_relative 'announcement' require_relative 'announcement'
#读取配置文件 #读取配置文件
load_config load_config
...@@ -23,11 +23,14 @@ begin ...@@ -23,11 +23,14 @@ begin
#读取命令行参数 #读取命令行参数
log = "log.log" log = "log.log"
log_level = "INFO"
profile = nil profile = nil
ARGV.each do |arg| ARGV.each do |arg|
case arg case arg
when /--log=(.*)/ when /--log=(.*)/
log.replace $1 log.replace $1
when /--log-level=(.*)/
log_level.replace $1
when /--profile=(.*)/ when /--profile=(.*)/
profile = $1 profile = $1
end end
...@@ -36,6 +39,7 @@ begin ...@@ -36,6 +39,7 @@ begin
#初始化SDL #初始化SDL
require 'sdl' require 'sdl'
include SDL include SDL
SDL.putenv ("SDL_VIDEO_CENTERED=1");
SDL.init(INIT_VIDEO | INIT_AUDIO) SDL.init(INIT_VIDEO | INIT_AUDIO)
WM::set_caption("MyCard", "MyCard") WM::set_caption("MyCard", "MyCard")
WM::icon = Surface.load("graphics/system/icon.gif") WM::icon = Surface.load("graphics/system/icon.gif")
...@@ -51,7 +55,7 @@ begin ...@@ -51,7 +55,7 @@ begin
log = STDOUT log = STDOUT
end end
$log = Logger.new(log) $log = Logger.new(log)
$log.level = Logger.const_get log_level
#性能分析 #性能分析
if profile if profile
if profile == "STDOUT" if profile == "STDOUT"
...@@ -82,7 +86,7 @@ begin ...@@ -82,7 +86,7 @@ begin
$scene.main while $scene $scene.main while $scene
rescue Exception => exception rescue Exception => exception
exception.backtrace.each{|backtrace|break if backtrace =~ /^(.*)\.rb:\d+:in `.*'"$/} #由于脚本是从main.rb开始执行的,总会有个能匹配成功的文件 exception.backtrace.each{|backtrace|break if backtrace =~ /^(.*)\.rb:\d+:in `.*'"$/} #由于脚本是从main.rb开始执行的,总会有个能匹配成功的文件
$log.fatal($1){[exception.inspect, *exception.backtrace].join("\n")} $log.fatal($1){[exception.inspect, *exception.backtrace].collect{|str|str.encode("UTF-8")}.join("\n")}
$game.exit if $game $game.exit if $game
require_relative 'scene_error' require_relative 'scene_error'
$scene = Scene_Error.new $scene = Scene_Error.new
......
require_relative '../iduel/action'
\ No newline at end of file
#encoding: UTF-8
class Game_Event
def self.parse(info, host=nil)
if host #来自大厅的udp消息
info =~ /^(\w*)\|(.*)$/m
case $1
when "NewUser"
NewUser
when "NewRoom"
NewRoom
when "MissingUser"
MissingUser
when "MissingRoom"
MissingRoom
else
Error
end.parse($2, host)
else #来自房间的消息
case info
when /▓SetName:(.*)▓/
NewUser
when /\[VerInf\]|\[LinkOK\]\|(.*)/
VerInf
when /(\[☆\]开启 游戏王NetBattleX Version .*\r\n\[.*年.*月.*日禁卡表\]\r\n)▊▊▊.*/
PlayerJoin
when /关闭游戏王NetBattleX .*▊▊▊.*/
PlayerLeave
when /(\[\d+\] .*|(?:#{::Action::CardFilter}\r\n)*)▊▊▊.*/m
Action
else
Error
end.parse($1)
end
end
class NewUser
def self.parse(info, host=$game.room.player2.id)
username, need_reply = info.split(',')
username = "对手" if username.nil? or username.empty?
user = User.new(host, username)
need_reply = need_reply == "1"
if need_reply and user != $game.user #忽略来自自己的回复请求
$game.send(user, 'NewUser', $game.user.name)
if $game.room and $game.room.player1 == $game.user #如果自己是主机
if $game.room.player2
$game.send(user, "NewRoom", $game.room.player1.name,$game.room.player2.name, $game.room.player2.host)
else
$game.send(user, "NewRoom", $game.room.player1.name)
end
end
end
self.new user
end
end
class NewRoom
attr_reader :room
def self.parse(info, host)
player1_name, player2_name, player2_host = info.split(',')
player1 = User.new(player1_name, host)
player2 = User.new(player2_name, player2_host) if player2_name
self.new Room.new(player1.id, player1.name, player1, player2)
end
end
class PlayerJoin
def self.parse(info)
#$game.room.player2.name = info
#self.new $game.room.player2
end
end
class PlayerLeave
def self.parse(info)
self.new
end
end
class Action
def self.parse(info)
self.new ::Action.parse(info), info
end
end
#以下NBX专有
class VerInf
def self.parse(info)
end
end
end
#encoding: UTF-8
class NBX < Game
Version = "20090622"
Port=2583
RS = "¢"
def initialize
super
require 'digest/md5'
load File.expand_path('action.rb', File.dirname(__FILE__))
load File.expand_path('event.rb', File.dirname(__FILE__))
load File.expand_path('user.rb', File.dirname(__FILE__))
end
def login(username)
connect
Game_Event.push Game_Event::Login.new(User.new('localhost', username)) if @conn_lobby
end
def host(name=@user.name)
@room = Room.new(@user.id, name, @user)
Game_Event.push Game_Event::Host.new(@room)
send(nil, "NewRoom", @room.player1.name)
@conn_room_server = TCPServer.new '0.0.0.0', Port #为了照顾NBX强制IPv4
@accept_room = Thread.new{(Thread.start(@conn_room_server.accept) {|client| accept(client)} while @conn_room_server) rescue nil}
end
def action(action)
if @room.player2
action.from_player = false
send(:room, action.escape)
action.from_player = true
end
end
def refresh
send(nil, 'NewUser', @user.name, 1)
end
def join(host, port=Port)
Thread.new do
begin
connect_loop TCPSocket.new(host, port)
rescue
Game_Event.push Game_Event::Error.new("网络错误", "连接服务器失败")
$log.error [exception.inspect, *exception.backtrace].join("\n")
end
end
end
def exit
send(:room, "关闭游戏王NetBattleX 2.7.2▊▊▊730462") rescue nil
@recv_lobby.kill rescue nil
@conn_lobby.close rescue nil
@conn_lobby = nil
@conn_room.close rescue nil
@conn_room = nil
@conn_room_server.close rescue nil
@conn_room_server = nil
end
def exit_room
end
private
def send(user, head, *args)
case user
when User #大厅里给特定用户的回复
@conn_lobby.send("#{head}|#{args.join(',')}", 0, user.host, Port) if @conn_lobby
when nil #大厅里的广播
@conn_lobby.send("#{head}|#{args.join(',')}", 0, '<broadcast>', Port) if @conn_lobby
when :room #房间里,发给对手和观战者
@conn_room.write(head.gsub("\n", "\r\n") + RS) if @conn_room
when :watchers #房间里,发给观战者
end
end
def connect
require 'socket'
require 'open-uri'
begin
@conn_lobby = UDPSocket.new
@conn_lobby.setsockopt(Socket::SOL_SOCKET, Socket::SO_BROADCAST, true)
@conn_lobby.bind('0.0.0.0', Port)
Thread.abort_on_exception = true
@recv_lobby = Thread.new do
begin
recv *@conn_lobby.recvfrom(1024) while @conn_lobby
rescue Exception => exception
self.exit
Game_Event.push Game_Event::Error.new(exception.class.to_s, exception.message)
$log.error('nbx-connect-1') {[exception.inspect, *exception.backtrace].join("\n")}
end
end
rescue Errno::EADDRINUSE
self.exit
Game_Event.push Game_Event::Error.new("局域网", "局域网模式不支持双开")
rescue Exception => exception
self.exit
Game_Event.push Game_Event::Error.new(exception.class.to_s, exception.message)
$log.error('nbx-connect-2') {[exception.inspect, *exception.backtrace].join("\n")}
end
end
def accept(client)
if @conn_room #如果已经连接了,进入观战
else #连接
connect_loop(client)
end
end
def recv_room(info)
info.chomp!(RS)
info.gsub!("\r\n", "\n")
$log.info ">> #{info}"
Game_Event.push Game_Event.parse info
end
def connect_loop(conn)
@conn_room = conn
begin
@conn_room.set_encoding "GBK", "UTF-8", :invalid => :replace, :undef => :replace
@room = Room.new(@user.id, @user.name, @user)
Game_Event.push Game_Event::Join.new(@room)
send(:room, "[VerInf]|#{Version}")
send(:room, "▓SetName:#{@user.name}▓")
send(:room, "[☆]开启 游戏王NetBattleX Version 2.7.0\r\n[10年3月1日禁卡表]\r\n▊▊▊E8CB04")
@room.player2 = User.new(conn.addr[2], "对手")
while info = @conn_room.gets(RS)
recv_room(info)
end
rescue Exception => exception
Game_Event.push Game_Event::Error.new(exception.class.to_s, exception.message)
$log.error('nbx-connect-loop') { [exception.inspect, *exception.backtrace].join("\n")}
ensure
@conn_room.close
@conn_room = nil
end
end
def recv(info, addrinfo)
$log.info ">> #{info} -- #{addrinfo[2]}"
Socket.ip_address_list.each do |localhost_addrinfo|
if localhost_addrinfo.ip_address == addrinfo[3]
addrinfo[2] = 'localhost'
break
end
end
Game_Event.push Game_Event.parse(info, addrinfo[2])
end
end
$game = NBX.new
$config[$config['game']]['username'] ||= ENV['USERNAME']
save_config
$game.login $config[$config['game']]['username']
name: 局域网
\ No newline at end of file
class User
def avatar(size=:small)
Surface.load("#{ENV['TEMP']}/#{ENV['USERNAME']}.bmp") rescue Surface.new(SWSURFACE, 1, 1, 32, 0,0,0,0)
end
end
...@@ -46,14 +46,17 @@ class Scene ...@@ -46,14 +46,17 @@ class Scene
# ● 开始处理 # ● 开始处理
#-------------------------------------------------------------------------- #--------------------------------------------------------------------------
def start def start
if $config['bgm'] and @@last_bgm != self.class::BGM if $config['bgm'] and @@last_bgm != bgm
@@bgm.destroy if @@bgm @@bgm.destroy if @@bgm
@@bgm = Mixer::Music.load "audio/bgm/#{self.class::BGM}" @@bgm = Mixer::Music.load "audio/bgm/#{bgm}"
Mixer.fade_in_music(@@bgm, -1, 800) Mixer.fade_in_music(@@bgm, -1, 800)
@bgm_window = Window_BGM.new OggInfo.new("audio/bgm/#{self.class::BGM}", "UTF-8").tag["title"] @bgm_window = Window_BGM.new OggInfo.new("audio/bgm/#{bgm}", "UTF-8").tag["title"]
@@last_bgm = self.class::BGM @@last_bgm = bgm
end end
end end
def bgm
"title.ogg"
end
def last_bgm def last_bgm
@@last_bgm @@last_bgm
end end
...@@ -114,12 +117,12 @@ class Scene ...@@ -114,12 +117,12 @@ class Scene
when Key::F12 when Key::F12
$scene = Scene_Title.new $scene = Scene_Title.new
else else
$log.debug('unhandled event'){event.inspect} #$log.debug('unhandled event'){event.inspect}
end end
when Event::Quit when Event::Quit
$scene = nil $scene = nil
else else
$log.debug('unhandled event'){event.inspect} #$log.debug('unhandled event'){event.inspect}
end end
end end
def handle_game(event) def handle_game(event)
......
...@@ -21,7 +21,6 @@ class Scene_Duel < Scene ...@@ -21,7 +21,6 @@ class Scene_Duel < Scene
attr_reader :player_field_window attr_reader :player_field_window
attr_reader :opponent_field_window attr_reader :opponent_field_window
attr_reader :fieldback_window attr_reader :fieldback_window
BGM = "duel.ogg"
def initialize(room, deck=nil) def initialize(room, deck=nil)
super() super()
@room = room @room = room
...@@ -48,6 +47,9 @@ class Scene_Duel < Scene ...@@ -48,6 +47,9 @@ class Scene_Duel < Scene
create_chat_window create_chat_window
super super
end end
def bgm
"duel.ogg"
end
def create_action_window def create_action_window
@player_field_window.action_window = Window_Action.new @player_field_window.action_window = Window_Action.new
end end
......
...@@ -15,7 +15,6 @@ class Scene_Lobby < Scene ...@@ -15,7 +15,6 @@ class Scene_Lobby < Scene
require_relative 'chatmessage' require_relative 'chatmessage'
require_relative 'scene_duel' require_relative 'scene_duel'
attr_reader :chat_window attr_reader :chat_window
BGM = "lobby.ogg"
def start def start
WM::set_caption("MyCard - #{$config['game']} - #{$game.user.name}(#{$game.user.id})", "MyCard") WM::set_caption("MyCard - #{$config['game']} - #{$game.user.name}(#{$game.user.id})", "MyCard")
$game.refresh $game.refresh
...@@ -30,7 +29,9 @@ class Scene_Lobby < Scene ...@@ -30,7 +29,9 @@ class Scene_Lobby < Scene
@count = 0 @count = 0
super super
end end
def bgm
"lobby.ogg"
end
def handle(event) def handle(event)
case event case event
when Event::KeyDown when Event::KeyDown
......
...@@ -9,7 +9,6 @@ require_relative 'window_announcements' ...@@ -9,7 +9,6 @@ require_relative 'window_announcements'
require_relative 'window_login' require_relative 'window_login'
require_relative 'scene_replay' require_relative 'scene_replay'
require_relative 'scene_lobby' require_relative 'scene_lobby'
BGM = "title.ogg"
class Scene_Login < Scene class Scene_Login < Scene
def start def start
WM::set_caption("MyCard", "MyCard") WM::set_caption("MyCard", "MyCard")
......
...@@ -5,7 +5,7 @@ class Scene_Replay < Scene_Watch ...@@ -5,7 +5,7 @@ class Scene_Replay < Scene_Watch
@replay = replay @replay = replay
@count = 0 @count = 0
super(@replay.room) super(@replay.room)
$log.debug('scene_reply'){'inited'} $log.info('scene_reply'){'inited'}
end end
def init_replay def init_replay
end end
......
#encoding: UTF-8 #encoding: UTF-8
#============================================================================== #==============================================================================
# �Scene_Title # �Scene_Title
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
# 銆�itle # �title
#============================================================================== #==============================================================================
require_relative 'scene' require_relative 'scene'
require_relative 'window_title' require_relative 'window_title'
...@@ -20,6 +20,7 @@ class Scene_Title < Scene ...@@ -20,6 +20,7 @@ class Scene_Title < Scene
#@logo_window.contents = logo #@logo_window.contents = logo
#$screen.update_rect(0,0,0,0) #$screen.update_rect(0,0,0,0)
@decision_se = Mixer::Wave.load("audio/se/decision.ogg") @decision_se = Mixer::Wave.load("audio/se/decision.ogg")
super super
end end
......
...@@ -4,17 +4,13 @@ class Widget_InputBox < Window ...@@ -4,17 +4,13 @@ class Widget_InputBox < Window
attr_accessor :type attr_accessor :type
require 'tk' require 'tk'
@@font = TkFont.new( Root=TkRoot.new{
"family" => 'WenQuanYi Micro Hei', #TODO: 直接调用一个.ttf文件,而不是把字体装到系统中
"size" => 15 #这字号尼玛?!
)
@@root=TkRoot.new{
withdraw withdraw
overrideredirect true overrideredirect true
attributes :topmost, true attributes :topmost, true
} }
@@entry = TkEntry.new(@@root){ Entry = TkEntry.new(Root){
font @@font font TkFont.new "family" => 'WenQuanYi Micro Hei', "size" => 15
validate :focusout validate :focusout
validatecommand {Widget_InputBox.determine} validatecommand {Widget_InputBox.determine}
bind('Key-Return'){self.value="" if @@active.proc.call(get.encode("UTF-8")) if @@active.proc;true} #两个if的解释:当存在proc时,call那个proc,如果执行结果为真就清空value bind('Key-Return'){self.value="" if @@active.proc.call(get.encode("UTF-8")) if @@active.proc;true} #两个if的解释:当存在proc时,call那个proc,如果执行结果为真就清空value
...@@ -39,22 +35,22 @@ class Widget_InputBox < Window ...@@ -39,22 +35,22 @@ class Widget_InputBox < Window
@font.draw_blended_utf8(@contents, @type == :password ? '*' * @value.size : @value, 2, 0, 0x00, 0x00, 0x00) unless @value.empty? @font.draw_blended_utf8(@contents, @type == :password ? '*' * @value.size : @value, 2, 0, 0x00, 0x00, 0x00) unless @value.empty?
end end
def clicked def clicked
@@entry.value = @value Entry.value = @value
@@entry.show @type == :password ? '*' : nil Entry.show @type == :password ? '*' : nil
@@entry.focus :force Entry.focus :force
@@entry.width @width Entry.width @width
@@root.geometry "#{@width}x#{@height}+#{@x+TkWinfo.pointerx(@@root)-Mouse.state[0]}+#{@y+TkWinfo.pointery(@@root)-Mouse.state[1]}" #根据鼠标位置来确定游戏窗口的相对位置,点击的瞬间鼠标移动了的话会有误差 Root.geometry "#{@width}x#{@height}+#{@x+TkWinfo.pointerx(Root)-Mouse.state[0]}+#{@y+TkWinfo.pointery(Root)-Mouse.state[1]}" #根据鼠标位置来确定游戏窗口的相对位置,点击的瞬间鼠标移动了的话会有误差
@@root.deiconify Root.deiconify
@@active = self #TODO:存在线程安全问题 @@active = self #TODO:存在线程安全问题
end end
def clear(x=0, y=0, width=@width, height=@height) def clear(x=0, y=0, width=@width, height=@height)
@contents.fill_rect(x,y,width,height,0x66FFFFFF) @contents.fill_rect(x,y,width,height,0x110000FF)
@contents.fill_rect(x+2,y+2,width-4,height-4,0xFFFFFFFF) @contents.fill_rect(x+2,y+2,width-4,height-4,0xFFFFFFFF)
end end
def update def update
#puts "UPDATE:" + self.to_s #puts "UPDATE:" + self.to_s
end end
def self.determine def self.determine
@@active.value=@@entry.get.encode("UTF-8");@@root.withdraw(true);@@active.refresh;true @@active.value=Entry.get.encode("UTF-8");Root.withdraw(true);@@active.refresh;true
end end
end end
...@@ -87,4 +87,8 @@ class Widget_Msgbox < Window ...@@ -87,4 +87,8 @@ class Widget_Msgbox < Window
@proc.call(@index) if @proc @proc.call(@index) if @proc
self.destroy self.destroy
end end
def self.destroy
instance = $scene.windows.find{|window|window.class == self and !window.destroyed?}
instance.destroy if instance
end
end end
...@@ -58,7 +58,7 @@ class Window_GameSelect < Window_List ...@@ -58,7 +58,7 @@ class Window_GameSelect < Window_List
end end
def clicked def clicked
return unless @index return unless @index
load @items[@index]["file"] #TODO: load的这种架构微蛋疼,一时想不到更好的方案 load @items[@index]["file"].encode("GBK") #TODO: load的这种架构微蛋疼,一时想不到更好的方案
$config['game'] = @items[@index]['name'] $config['game'] = @items[@index]['name']
@login_window.destroy if @login_window @login_window.destroy if @login_window
@login_window = Window_Login.new(316,316,$config[$config['game']]["username"],$config[$config['game']]["password"]) @login_window = Window_Login.new(316,316,$config[$config['game']]["username"],$config[$config['game']]["password"])
......
...@@ -2,11 +2,11 @@ ...@@ -2,11 +2,11 @@
class Window_Host < Window class Window_Host < Window
attr_reader :index attr_reader :index
def initialize(x,y) def initialize(x,y)
super(x,y,300,150,300)
@button = Surface.load("graphics/system/button.png") @button = Surface.load("graphics/system/button.png")
@items = {:ok => [116,114,@button.w/3,@button.h]} @items = {:ok => [116,114,@button.w/3,@button.h]}
@buttons = {:ok => "确定"} @buttons = {:ok => "确定"}
@background = Surface.load('graphics/system/msgbox.png').display_format @background = Surface.load('graphics/system/msgbox.png').display_format
super((1024-@background.w)/2, 230, @background.w, @background.h)
@font = TTF.open("fonts/WenQuanYi Micro Hei.ttf", 16) @font = TTF.open("fonts/WenQuanYi Micro Hei.ttf", 16)
@title_color = [0xFF, 0xFF, 0xFF] @title_color = [0xFF, 0xFF, 0xFF]
@color = [0x04, 0x47, 0x7c] @color = [0x04, 0x47, 0x7c]
...@@ -63,11 +63,14 @@ class Window_Host < Window ...@@ -63,11 +63,14 @@ class Window_Host < Window
when :ok when :ok
return if @roomname_inputbox.value.empty? return if @roomname_inputbox.value.empty?
@joinroom_msgbox = Widget_Msgbox.new("建立房间", "正在建立房间") @joinroom_msgbox = Widget_Msgbox.new("建立房间", "正在建立房间")
destroy
$game.host(@roomname_inputbox.value, :pvp => @pvp.checked?, :match => @match.checked?) $game.host(@roomname_inputbox.value, :pvp => @pvp.checked?, :match => @match.checked?)
@roomname_inputbox.destroy
@pvp.destroy
@match.destroy
self.destroy
end end
end end
def destroy
@roomname_inputbox.destroy
@pvp.destroy
@match.destroy
super
end
end end
\ No newline at end of file
...@@ -30,7 +30,7 @@ class Window_RoomList < Window_Scrollable ...@@ -30,7 +30,7 @@ class Window_RoomList < Window_Scrollable
@font.draw_blended_utf8(@contents, room.name, 128, y+8, *room.color) unless room.name.empty? or room.name.size > 100 @font.draw_blended_utf8(@contents, room.name, 128, y+8, *room.color) unless room.name.empty? or room.name.size > 100
$log.error('标题过长') {room.name} if room.name.size > 100 $log.error('标题过长') {room.name} if room.name.size > 100
@font.draw_blended_utf8(@contents, room.player1.name, 128, y+24, *room.player1.color) if room.player1 @font.draw_blended_utf8(@contents, room.player1.name, 128, y+24, *room.player1.color) if room.player1
@font.draw_blended_utf8(@contents, room.player2.name, 256, y+24, *room.player2.color) if room.player2 @font.draw_blended_utf8(@contents, room.player2.name, 320, y+24, *room.player2.color) if room.player2
room.extra.each_with_index do |extra, index| room.extra.each_with_index do |extra, index|
str, color = extra str, color = extra
@font.draw_blended_utf8(@contents, str, 300+index*96, y+8, *color) @font.draw_blended_utf8(@contents, str, 300+index*96, y+8, *color)
......
#encoding: UTF-8 #encoding: UTF-8
class Game_Event class Game_Event
User_Filter = /<li>(:::观战:|===决斗1=|===决斗2=)<font color="(?:blue|gray)">(.+?)(\(未认证\)|)<\/font>;<\/li>/ User_Filter = /\[(\d+),<font color="(?:blue|gray)">(.+?)(\(未认证\)|)<\/font>\]/
Room_Filter = /<div style="width:300px; height:150px; border:1px #ececec solid; float:left;padding:5px; margin:5px;">房间名称:(.+?)(<font color="d28311" title="竞技场模式">\[竞\]<\/font>|) (<font color=(?:\")?red(?:\")?>决斗已开始!<\/font>|<font color=(?:\")?blue(?:\")?>等待<\/font>)<font size="1">\(ID:(\d+)\)<\/font>#{User_Filter}+?<\/div>/ Room_Filter = /\[(\d+),(.+?),(wait|start)#{User_Filter}+?\]/
#User_Filter = /<li>(:::观战:|===决斗1=|===决斗2=)<font color="(?:blue|gray)">(.+?)(\(未认证\)|)<\/font>;<\/li>/
#Room_Filter = /<div style="width:300px; height:150px; border:1px #ececec solid; float:left;padding:5px; margin:5px;">房间名称:(.+?)(<font color="d28311" title="竞技场模式">\[竞\]<\/font>|) (<font color=(?:\")?red(?:\")?>决斗已开始!<\/font>|<font color=(?:\")?blue(?:\")?>等待<\/font>)<font size="1">\(ID:(\d+)\)<\/font>#{User_Filter}+?<\/div>/
class AllRooms < Game_Event class AllRooms < Game_Event
def self.parse(info) def self.parse(info)
@rooms = [] @rooms = []
info.scan(Room_Filter) do |name, pvp, status, id| info.scan(Room_Filter) do |id, name, status|
player1 = player2 = nil player1 = player2 = nil
$&.scan(User_Filter) do |player, name, certified| $&.scan(User_Filter) do |player, name, certified|
if player["1"] if player["1"]
...@@ -14,12 +16,13 @@ class Game_Event ...@@ -14,12 +16,13 @@ class Game_Event
player2 = User.new(name.to_sym, name, certified.empty?) player2 = User.new(name.to_sym, name, certified.empty?)
end end
end end
room = Room.new(id.to_i, name, player1, player2, false, status["等待"] ? [0,0,255] : [255,0,0]) room = Room.new(id.to_i, name, player1, player2, false, [0,0,0])
room.status = status.to_sym
room.name =~ /^(P)?(M)?\#?(.*)$/ room.name =~ /^(P)?(M)?\#?(.*)$/
room.name = $3 room.name = $3
room.pvp = !!$1 room.pvp = !!$1
room.match = !!$2 room.match = !!$2
if status["等待"] if status == "wait"
@rooms.unshift room @rooms.unshift room
else else
@rooms << room @rooms << room
......
#encoding: UTF-8 #encoding: UTF-8
load File.expand_path('window_login.rb', File.dirname(__FILE__)) load File.expand_path('window_login.rb', File.dirname(__FILE__))
require 'open-uri'
class Ygocore < Game class Ygocore < Game
config = YAML.load_file("lib/ygocore/server.yml")
Register_Url = config['register']
Port = config['port']
Server = config['server']
API_Url = config['api']
Index_Url = config['index']
attr_reader :password attr_reader :password
@@config = YAML.load_file("lib/ygocore/server.yml")
def initialize def initialize
super super
load File.expand_path('event.rb', File.dirname(__FILE__)) load File.expand_path('event.rb', File.dirname(__FILE__))
load File.expand_path('user.rb', File.dirname(__FILE__)) load File.expand_path('user.rb', File.dirname(__FILE__))
load File.expand_path('room.rb', File.dirname(__FILE__)) load File.expand_path('room.rb', File.dirname(__FILE__))
load File.expand_path('scene_lobby.rb', File.dirname(__FILE__)) load File.expand_path('scene_lobby.rb', File.dirname(__FILE__))
require 'json'
end end
def login(username, password) def login(username, password)
if username.empty? if username.empty?
...@@ -24,22 +19,21 @@ class Ygocore < Game ...@@ -24,22 +19,21 @@ class Ygocore < Game
Widget_Msgbox.new("登陆", "无密码登陆,不能建房,不能加入竞技场", :ok => "确定"){Game_Event.push Game_Event::Login.new(User.new(username.to_sym, username))} Widget_Msgbox.new("登陆", "无密码登陆,不能建房,不能加入竞技场", :ok => "确定"){Game_Event.push Game_Event::Login.new(User.new(username.to_sym, username))}
else else
require 'cgi' require 'cgi'
open("#{API_Url}?userregist=CHANGEPASS&username=#{CGI.escape username}&password=#{CGI.escape password}&oldpass=#{CGI.escape password}") do |file| result = open("#{@@config['api']}?operation=passcheck&username=#{CGI.escape username}&pass=#{CGI.escape password}") do |file|
file.set_encoding "GBK" file.set_encoding "GBK"
result = file.read.encode("UTF-8") result = file.read.encode("UTF-8")
$log.debug('用户登陆传回消息'){result} $log.info('用户登陆传回消息'){result}
case result result
when "修改成功" end rescue nil
connect case result
@password = password when "true"
Game_Event.push Game_Event::Login.new(User.new(username.to_sym, username)) connect
when "用户注册禁止" @password = password
connect Game_Event.push Game_Event::Login.new(User.new(username.to_sym, username))
@password = password when "false"
Widget_Msgbox.new("登陆", "验证关闭,加房连接断开请自行检查密码", :ok => "确定"){Game_Event.push Game_Event::Login.new(User.new(username.to_sym, username))} Game_Event.push Game_Event::Error.new("登陆", "用户名或密码错误")
else else
Game_Event.push Game_Event::Error.new("登陆", "用户名或密码错误") Widget_Msgbox.new("登陆", "连接服务器失败", :ok => "确定")
end
end end
end end
end end
...@@ -47,7 +41,9 @@ class Ygocore < Game ...@@ -47,7 +41,9 @@ class Ygocore < Game
if $game.password.nil? or $game.password.empty? if $game.password.nil? or $game.password.empty?
return Widget_Msgbox.new("建立房间", "必须有账号才能建立房间", :ok => "确定") return Widget_Msgbox.new("建立房间", "必须有账号才能建立房间", :ok => "确定")
end end
return unless ygocore_path if !ygocore_path
return Widget_Msgbox.destroy
end
room = Room.new(0, room_name) room = Room.new(0, room_name)
room.pvp = room_config[:pvp] room.pvp = room_config[:pvp]
room.match = room_config[:match] room.match = room_config[:match]
...@@ -66,7 +62,9 @@ class Ygocore < Game ...@@ -66,7 +62,9 @@ class Ygocore < Game
if $game.password.nil? or $game.password.empty? and room.pvp? if $game.password.nil? or $game.password.empty? and room.pvp?
return Widget_Msgbox.new("加入房间", "必须有账号才能加入竞技场房间", :ok => "确定") return Widget_Msgbox.new("加入房间", "必须有账号才能加入竞技场房间", :ok => "确定")
end end
return unless ygocore_path if !ygocore_path
return Widget_Msgbox.destroy
end
refresh do refresh do
if room.full? #如果游戏已经开了 if room.full? #如果游戏已经开了
Widget_Msgbox.new("加入房间", "游戏已经开始", :ok => "确定") Widget_Msgbox.new("加入房间", "游戏已经开始", :ok => "确定")
...@@ -80,7 +78,7 @@ class Ygocore < Game ...@@ -80,7 +78,7 @@ class Ygocore < Game
def refresh def refresh
Thread.new do Thread.new do
begin begin
open(API_Url) do |file| open("#{@@config['api']}?operation=getroom") do |file|
file.set_encoding("GBK") file.set_encoding("GBK")
info = file.read.encode("UTF-8") info = file.read.encode("UTF-8")
Game_Event.push Game_Event::AllUsers.parse info Game_Event.push Game_Event::AllUsers.parse info
...@@ -93,26 +91,39 @@ class Ygocore < Game ...@@ -93,26 +91,39 @@ class Ygocore < Game
def ygocore_path def ygocore_path
return $config['ygocore']['path'] if $config['ygocore']['path'] and File.file? $config['ygocore']['path'] return $config['ygocore']['path'] if $config['ygocore']['path'] and File.file? $config['ygocore']['path']
return if @last_clicked and Time.now - @last_clicked < 3 #防止重复点击 return if @last_clicked and Time.now - @last_clicked < 3 #防止重复点击
Widget_Msgbox.new("加入房间", "请指定ygocore主程序位置") msgbox = Widget_Msgbox.new("加入房间", "请指定ygocore主程序位置")
$scene.draw $scene.draw
require 'tk' require 'tk'
$config['ygocore']['path'] = Tk.getOpenFile.encode("UTF-8") $config['ygocore']['path'] = Tk.getOpenFile.encode("UTF-8")
save_config save_config
msgbox.destroy
@last_clicked = Time.now @last_clicked = Time.now
end end
def self.register
require 'launchy'
Launchy.open @@config['register']
end
def server
@@config['server']
end
def port
@@config['port']
end
private private
def connect def connect
require 'open-uri'
end end
def self.get_announcements def self.get_announcements
#公告 #公告
$config['ygocore']['announcements'] ||= [Announcement.new("正在读取公告...", nil, nil)] $config['ygocore']['announcements'] ||= [Announcement.new("正在读取公告...", nil, nil)]
Thread.new do Thread.new do
begin begin
open(API_Url) do |file| require 'open-uri'
open(@@config['api']) do |file|
file.set_encoding "GBK" file.set_encoding "GBK"
announcements = [] announcements = []
file.read.encode("UTF-8").scan(/<div style="color:red" >公告:(.*?)<\/div>/).each do |title,others| file.read.encode("UTF-8").scan(/<div style="color:red" >公告:(.*?)<\/div>/).each do |title,others|
announcements << Announcement.new(title, Index_Url, nil) announcements << Announcement.new(title, @@config['index'], nil)
end end
$config['ygocore']['announcements'].replace announcements $config['ygocore']['announcements'].replace announcements
save_config save_config
......
...@@ -2,10 +2,11 @@ ...@@ -2,10 +2,11 @@
class Room class Room
attr_accessor :pvp attr_accessor :pvp
attr_accessor :match attr_accessor :match
attr_writer :status
alias pvp? pvp alias pvp? pvp
alias match? match alias match? match
def full? def full?
color == [255,0,0] #方法不规范 凑合用 @status == :start
end end
def extra def extra
result = {} result = {}
......
...@@ -11,7 +11,7 @@ class Scene_Lobby ...@@ -11,7 +11,7 @@ class Scene_Lobby
CF_UNICODETEXT = 13; CF_UNICODETEXT = 13;
GMEM_DDESHARE = 0x2000; GMEM_DDESHARE = 0x2000;
def join(room) def join(room)
return unless $game.ygocore_path path = $game.ygocore_path
room_name = if room.pvp? and room.match? room_name = if room.pvp? and room.match?
"PM#" + room.name "PM#" + room.name
...@@ -25,8 +25,8 @@ class Scene_Lobby ...@@ -25,8 +25,8 @@ class Scene_Lobby
$scene.draw $scene.draw
#写入配置文件并运行ygocore #写入配置文件并运行ygocore
Dir.chdir(File.dirname($game.ygocore_path)) do Dir.chdir(File.dirname(path)) do
$log.debug('当前目录'){Dir.pwd.encode("UTF-8")} $log.info('当前目录'){Dir.pwd.encode("UTF-8")}
system_conf = {} system_conf = {}
begin begin
IO.readlines('system.conf').each do |line| IO.readlines('system.conf').each do |line|
...@@ -40,14 +40,14 @@ class Scene_Lobby ...@@ -40,14 +40,14 @@ class Scene_Lobby
system_conf['textfont'] = 'c:/windows/fonts/simsun.ttc 14' system_conf['textfont'] = 'c:/windows/fonts/simsun.ttc 14'
system_conf['numfont'] = 'c:/windows/fonts/arialbd.ttf' system_conf['numfont'] = 'c:/windows/fonts/arialbd.ttf'
$log.error('找不到system.conf') $log.error('找不到system.conf')
$log.debug(Dir.foreach('.').to_a.inspect) $log.info(Dir.foreach('.').to_a.inspect)
end end
system_conf['nickname'] = "#{$game.user.name}#{"$" unless $game.password.nil? or $game.password.empty?}#{$game.password}" system_conf['nickname'] = "#{$game.user.name}#{"$" unless $game.password.nil? or $game.password.empty?}#{$game.password}"
system_conf['lastip'] = Ygocore::Server system_conf['lastip'] = $game.server
system_conf['lastport'] = Ygocore::Port.to_s system_conf['lastport'] = $game.port.to_s
open('system.conf', 'w') {|file|file.write system_conf.collect{|key,value|"#{key} = #{value}"}.join("\n")} open('system.conf', 'w') {|file|file.write system_conf.collect{|key,value|"#{key} = #{value}"}.join("\n")}
$log.debug('ygocore路径') {$config['ygocore']['path']} $log.info('ygocore路径') {path}
IO.popen("\"#{$config['ygocore']['path']}\"".encode("GBK")) #执行外部程序....有中文的情况下貌似只能这样了orz IO.popen("\"#{path}\"".encode("GBK")) #执行外部程序....有中文的情况下貌似只能这样了orz
end end
#初始化windows API #初始化windows API
require 'win32api' require 'win32api'
...@@ -79,11 +79,11 @@ class Scene_Lobby ...@@ -79,11 +79,11 @@ class Scene_Lobby
@@SendMessage.call(hwnd, WM_LBUTTONUP, 0, MAKELPARAM(507,242)) @@SendMessage.call(hwnd, WM_LBUTTONUP, 0, MAKELPARAM(507,242))
sleep 0.5 sleep 0.5
if @@OpenClipboard.Call(0) != 0 if @@OpenClipboard.Call(0) != 0
$log.debug('加入房间'){room_name} $log.info('加入房间'){room_name}
@@EmptyClipboard.Call(); @@EmptyClipboard.Call();
p len = room_name.encode("UTF-16LE").bytesize len = room_name.encode("UTF-16LE").bytesize
#p len=@@lstrlen.call(room_name.encode("UTF-16LE"))# #p len=@@lstrlen.call(room_name.encode("UTF-16LE"))#
$log.debug('房间名长度'){len.to_s} $log.info('房间名长度'){len.to_s}
hmem = @@GlobalAlloc.Call(GMEM_DDESHARE, len+2); hmem = @@GlobalAlloc.Call(GMEM_DDESHARE, len+2);
pmem = @@GlobalLock.Call(hmem); pmem = @@GlobalLock.Call(hmem);
@@lstrcpy.Call(pmem, room_name.encode("UTF-16LE")); @@lstrcpy.Call(pmem, room_name.encode("UTF-16LE"));
...@@ -103,7 +103,7 @@ class Scene_Lobby ...@@ -103,7 +103,7 @@ class Scene_Lobby
@@keybd_event.call(VK_TAB,0,KEYEVENTF_KEYUP,0) @@keybd_event.call(VK_TAB,0,KEYEVENTF_KEYUP,0)
@@keybd_event.call(VK_RETURN,0,0,0) @@keybd_event.call(VK_RETURN,0,0,0)
@@keybd_event.call(VK_RETURN,0,KEYEVENTF_KEYUP,0) @@keybd_event.call(VK_RETURN,0,KEYEVENTF_KEYUP,0)
Widget_Msgbox.new("加入房间","已经加入房间", :ok => "确定").destroy #仅仅为了消掉正在加入房间的消息框 Widget_Msgbox.destroy #仅仅为了消掉正在加入房间的消息框
else else
Widget_Msgbox.new("加入房间", '填写房间名失败 请把房间名手动填写到房间密码处', :ok => "确定") Widget_Msgbox.new("加入房间", '填写房间名失败 请把房间名手动填写到房间密码处', :ok => "确定")
end end
...@@ -111,7 +111,6 @@ class Scene_Lobby ...@@ -111,7 +111,6 @@ class Scene_Lobby
Widget_Msgbox.new("加入房间", 'ygocore运行失败', :ok => "确定") Widget_Msgbox.new("加入房间", 'ygocore运行失败', :ok => "确定")
end end
#这里似乎有个能引起ruby解释器崩溃的故障,但是没法稳定重现。 #这里似乎有个能引起ruby解释器崩溃的故障,但是没法稳定重现。
GC.start
end end
def MAKELPARAM(w1,w2) def MAKELPARAM(w1,w2)
return (w2<<16) | w1 return (w2<<16) | w1
......
---
register: http://sh.convnet.net:7955/regist.html register: http://sh.convnet.net:7955/regist.html
api: http://sh.convnet.net:7922/ api: http://sh.convnet.net:7922/
index: http://sh.convnet.net:7922/ index: http://sh.convnet.net:7922/
......
...@@ -11,9 +11,9 @@ class User ...@@ -11,9 +11,9 @@ class User
@certified = certified unless certified == :keep @certified = certified unless certified == :keep
end end
def color def color
@certified ? [0,0,255] : [128,128,128] @certified ? [0,0,0] : [128,128,128]
end end
def space def space
Widget_Msgbox.new("查看资料", "ygocore没有这个功能", :ok => "确定") Widget_Msgbox.new("查看资料", "功能未实现", :ok => "确定")
end end
end end
...@@ -13,8 +13,7 @@ class Window_Login ...@@ -13,8 +13,7 @@ class Window_Login
$game.login(@username_inputbox.value, @password_inputbox.value) $game.login(@username_inputbox.value, @password_inputbox.value)
@last_clicked = Time.now @last_clicked = Time.now
when :register when :register
require 'launchy' Ygocore.register
Launchy.open(Ygocore::Register_Url)
@last_clicked = Time.now @last_clicked = Time.now
#when :replay #when :replay
# require 'tk' # require 'tk'
......
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