Commit d4b6da98 authored by 神楽坂玲奈's avatar 神楽坂玲奈

登陆架构更改,卡图修正

parent 5c53e428
...@@ -24,7 +24,7 @@ end ...@@ -24,7 +24,7 @@ end
spec = Gem::Specification.new do |s| spec = Gem::Specification.new do |s|
s.name = 'mycard' s.name = 'mycard'
s.version = '0.4.8' s.version = '0.5.2'
s.extra_rdoc_files = ['README.txt', 'LICENSE.txt'] s.extra_rdoc_files = ['README.txt', 'LICENSE.txt']
s.summary = 'a card game' s.summary = 'a card game'
s.description = s.summary s.description = s.summary
...@@ -65,4 +65,4 @@ Rake::RDocTask.new do |rdoc| ...@@ -65,4 +65,4 @@ Rake::RDocTask.new do |rdoc|
rdoc.options << '--line-numbers' rdoc.options << '--line-numbers'
end end
CLOBBER.include %w(error-程序出错请到论坛反馈.txt log.log profile.log config.yml doc ygocore/pics) + list('replay') + list('ygocore/replay') + list('.').keep_if{|file|File.basename(file) == "Thumbs.db"} + list("graphics/avatars").keep_if{|file|File.basename(file) =~ /.*_(?:small|middle|large)\.png/} CLOBBER.include %w(error-程序出错请到论坛反馈.txt log.log profile.log config.yml doc ygocore/pics) + list('replay') + list('ygocore/replay') + list('.').keep_if{|file|File.basename(file) == "Thumbs.db"} + list("graphics/avatars").keep_if{|file|File.basename(file) =~ /.*_(?:small|middle|large)\.png/} + list("ygocore/deck").keep_if{|file|File.basename(file) != 'sample.ydk'}
\ No newline at end of file \ No newline at end of file
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
...@@ -32,6 +32,8 @@ class Game ...@@ -32,6 +32,8 @@ class Game
def watching? def watching?
@room and @room.include? @user @room and @room.include? @user
end end
def self.deck_edit
end
end end
...@@ -27,7 +27,7 @@ class User ...@@ -27,7 +27,7 @@ class User
yield result yield result
Thread.new do Thread.new do
open("http://www.duelcn.com/uc_server/avatar.php?uid=#{id-100000}&size=#{size}", 'rb') {|io|open(cache, 'wb') {|c|c.write io.read}} rescue cache = "graphics/avatars/noavatar_#{size}.gif" open("http://www.duelcn.com/uc_server/avatar.php?uid=#{id-100000}&size=#{size}", 'rb') {|io|open(cache, 'wb') {|c|c.write io.read}} rescue cache = "graphics/avatars/noavatar_#{size}.gif"
yield Surface.load(cache) if scene == $scene (yield Surface.load(cache) if scene == $scene) rescue nil
end end
else else
result result
......
...@@ -3,7 +3,7 @@ class Window_Login ...@@ -3,7 +3,7 @@ class Window_Login
return if @last_clicked and Time.now - @last_clicked < 3 #防止重复点击 return if @last_clicked and Time.now - @last_clicked < 3 #防止重复点击
case @index case @index
when :login when :login
Widget_Msgbox.new("iDuel", "正在登") Widget_Msgbox.new("iDuel", "正在登")
$scene.draw #强制重绘一次,下面会阻塞 $scene.draw #强制重绘一次,下面会阻塞
$game = Iduel.new $game = Iduel.new
$config[$config['game']]['username'] = @username_inputbox.value $config[$config['game']]['username'] = @username_inputbox.value
...@@ -15,12 +15,11 @@ class Window_Login ...@@ -15,12 +15,11 @@ class Window_Login
system("start #{Iduel::Register_Url}") system("start #{Iduel::Register_Url}")
@last_clicked = Time.now @last_clicked = Time.now
when :replay when :replay
require_relative '../dialog' file = Dialog.get_open_file("播放录像", "所有支持的录像 (*.txt;*.htm)" => "*.txt;*.htm", "iDuel的html的录像 (*.htm)" => "*.htm", "文本录像 (*.txt)" => "*.txt")
file = Dialog.get_open_file("播放战报", "所有支持的战报 (*.txt;*.htm)" => "*.txt;*.htm", "iDuel的html的战报 (*.htm)" => "*.htm", "文本战报 (*.txt)" => "*.txt")
if !file.empty? if !file.empty?
$game = Iduel.new $game = Iduel.new
$game.user = User.new(0) $game.user = User.new(0)
Widget_Msgbox.new("回放战报", "战报读取中...") Widget_Msgbox.new("回放录像", "录像读取中...")
$scene.draw $scene.draw
$log.info('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
......
...@@ -46,7 +46,7 @@ begin ...@@ -46,7 +46,7 @@ begin
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")
$screen = Screen.open($config['screen']['width'], $config['screen']['height'], 0, HWSURFACE | ($config['screen']['fullscreen'] ? FULLSCREEN : 0)) $screen = Screen.open($config['screen']['width'], $config['screen']['height'], 0, HWSURFACE | ($config['screen']['fullscreen'] ? FULLSCREEN : 0))
Mixer.open(Mixer::DEFAULT_FREQUENCY,Mixer::DEFAULT_FORMAT,Mixer::DEFAULT_CHANNELS,512) Mixer.open(Mixer::DEFAULT_FREQUENCY,Mixer::DEFAULT_FORMAT,Mixer::DEFAULT_CHANNELS,4096)
Mixer.set_volume_music(60) Mixer.set_volume_music(60)
TTF.init TTF.init
Thread.abort_on_exception = true Thread.abort_on_exception = true
...@@ -83,6 +83,8 @@ begin ...@@ -83,6 +83,8 @@ begin
require_relative 'update' require_relative 'update'
Update.start Update.start
require_relative 'dialog'
$log.info("main"){"初始化成功"} $log.info("main"){"初始化成功"}
rescue Exception => exception rescue Exception => exception
open('error-程序出错请到论坛反馈.txt', 'w'){|f|f.write [exception.inspect, *exception.backtrace].join("\n")} open('error-程序出错请到论坛反馈.txt', 'w'){|f|f.write [exception.inspect, *exception.backtrace].join("\n")}
......
...@@ -106,14 +106,14 @@ class Scene ...@@ -106,14 +106,14 @@ class Scene
when Mouse::BUTTON_LEFT when Mouse::BUTTON_LEFT
update_active_window(event.x, event.y) update_active_window(event.x, event.y)
@active_window.clicked if @active_window @active_window.clicked if @active_window
if !(@active_window.is_a? Widget_InputBox)
Widget_InputBox.focus = false
end
when 4 when 4
@active_window.scroll_up if @active_window @active_window.scroll_up if @active_window
when 5 when 5
@active_window.scroll_down if @active_window @active_window.scroll_down if @active_window
end end
if !@active_window.is_a? Widget_InputBox
Widget_InputBox.focus = false
end
when Event::MouseButtonUp when Event::MouseButtonUp
case event.button case event.button
when Mouse::BUTTON_LEFT when Mouse::BUTTON_LEFT
......
...@@ -23,7 +23,7 @@ class Scene_Lobby < Scene ...@@ -23,7 +23,7 @@ class Scene_Lobby < Scene
@userlist = Window_UserList.new(24,204,$game.users) @userlist = Window_UserList.new(24,204,$game.users)
@roomlist = Window_RoomList.new(320,50,$game.rooms) @roomlist = Window_RoomList.new(320,50,$game.rooms)
@userinfo = Window_UserInfo.new(24,24, $game.user) @userinfo = Window_UserInfo.new(24,24, $game.user)
@host_window = Window_LobbyButtons.new(900,16) @host_window = Window_LobbyButtons.new(830,18)
@active_window = @roomlist @active_window = @roomlist
@chat_window = Window_Chat.new(313,543,698,212) @chat_window = Window_Chat.new(313,543,698,212)
@count = 0 @count = 0
......
...@@ -43,31 +43,8 @@ class Scene_Title < Scene ...@@ -43,31 +43,8 @@ class Scene_Title < Scene
when 2 when 2
require_relative 'widget_msgbox' require_relative 'widget_msgbox'
require_relative 'scene_login' require_relative 'scene_login'
Widget_Msgbox.new("编辑卡组", "\"导入\"导入已有卡组,\"编辑\"启动ygocore", :import => "导入", :edit => "编辑") do |button| load 'lib/ygocore/game.rb' #TODO:不规范啊不规范
case button Ygocore.deck_edit
when:import
require_relative 'dialog'
file = Dialog.get_open_file("导入卡组", "ygocore卡组 (*.ydk)"=>"*.ydk")#"所有支持的卡组 (*.txt;*.deck;*.ydk)"=>"*.ydk;*.txt;*.deck","ygocore卡组 (*.ydk)"=>"*.ydk", "NBX/iDuel/狐查卡组 (*.txt)" => "*.txt", "图形组卡器卡组 (*.deck)"=>"*.deck")
if !file.empty?
open(file) do |src|
Dir.mkdir "ygocore/deck" unless File.directory?("ygocore/deck")
open("ygocore/deck/#{File.basename(file)}", 'w') do |dest|
dest.write src.read
end
Widget_Msgbox.new("导入卡组", "导入卡组完成", :ok => "确定")
end rescue Widget_Msgbox.new("导入卡组", "导入卡组失败", :ok => "确定")
end
when :edit
load 'lib/ygocore/game.rb' #TODO:不规范啊不规范
if !Update.images.empty?
Widget_Msgbox.new("加入房间", "卡图正在下载中,可能显示不出部分卡图", :ok => "确定"){Ygocore.run_ygocore(:deck)}
else
Ygocore.run_ygocore(:deck)
end
end
end
#require_relative 'scene_deck'
#Scene_Deck.new
when 3 when 3
require_relative 'scene_config' require_relative 'scene_config'
$scene = Scene_Config.new $scene = Scene_Config.new
......
...@@ -2,7 +2,7 @@ require 'open-uri' ...@@ -2,7 +2,7 @@ require 'open-uri'
require "fileutils" require "fileutils"
require_relative 'card' require_relative 'card'
module Update module Update
Version = '0.4.8' Version = '0.5.2'
URL = "http://card.touhou.cc/mycard/update.json?version=#{Version}" URL = "http://card.touhou.cc/mycard/update.json?version=#{Version}"
class <<self class <<self
attr_reader :thumbnails, :images, :status attr_reader :thumbnails, :images, :status
...@@ -20,7 +20,7 @@ module Update ...@@ -20,7 +20,7 @@ module Update
end end
f.extract{true} f.extract{true}
end end
end end rescue $log.error('安装更新出错'){file+$!.inspect+$!.backtrace.inspect}
Version.replace $2 Version.replace $2
File.delete file File.delete file
@updated = true @updated = true
...@@ -30,6 +30,9 @@ module Update ...@@ -30,6 +30,9 @@ module Update
IO.popen('./mycard') IO.popen('./mycard')
$scene = nil $scene = nil
end end
@images = []
@thumbnails = []
@status = '正在检查更新' @status = '正在检查更新'
Thread.new do Thread.new do
open(URL) do |file| open(URL) do |file|
...@@ -46,123 +49,92 @@ module Update ...@@ -46,123 +49,92 @@ module Update
open(name, 'wb') do |f| open(name, 'wb') do |f|
f.write fi.read f.write fi.read
end end
end rescue nil end rescue $log.error('下载更新'){'下载更新失败'}
end end
if File.file? "ygocore/cards.cdb" end rescue $log.error('检查更新'){'检查更新失败'}
require 'sqlite3' if File.file? "ygocore/cards.cdb"
db = SQLite3::Database.new( "ygocore/cards.cdb" ) require 'sqlite3'
@thumbnails = [] db = SQLite3::Database.new( "ygocore/cards.cdb" )
db.execute( "select id from datas" ) do |row| db.execute( "select id from datas" ) do |row|
@thumbnails << row[0] @thumbnails << row[0]
end end
@images = @thumbnails.dup @images.replace @thumbnails
if !File.directory?('ygocore/pics/thumbnail') if !File.directory?('ygocore/pics/thumbnail')
FileUtils.mkdir_p('ygocore/pics/thumbnail') FileUtils.mkdir_p('ygocore/pics/thumbnail')
end end
existed_thumbnails = [] existed_thumbnails = []
Dir.foreach("ygocore/pics/thumbnail") do |file| Dir.foreach("ygocore/pics/thumbnail") do |file|
if file =~ /(\d+)\.jpg/ if file =~ /(\d+)\.jpg/
existed_thumbnails << $1.to_i existed_thumbnails << $1.to_i
end
end end
@thumbnails -= existed_thumbnails end
$log.info('待下载的缩略卡图'){@thumbnails.inspect} @thumbnails -= existed_thumbnails
existed_images = [] existed_images = []
Dir.foreach("ygocore/pics") do |file| Dir.foreach("ygocore/pics") do |file|
if file =~ /(\d+)\.jpg/ if file =~ /(\d+)\.jpg/
existed_images << $1.to_i existed_images << $1.to_i
end
end end
@images -= existed_images end
existed_images = [] @images -= existed_images
if (!@images.empty? or !@thumbnails.empty?) and File.file?("#{Card::PicPath}/1.jpg") existed_images = []
db_mycard = SQLite3::Database.new( "data/data.sqlite" ) if (!@images.empty? or !@thumbnails.empty?) and File.file?("#{Card::PicPath}/1.jpg")
can_link = true db_mycard = SQLite3::Database.new( "data/data.sqlite" )
internal_can_link = true
db_mycard.execute( "select id, number from `yu-gi-oh` where number in (#{(@images+@thumbnails).uniq.collect{|number|"'%08d'" % number}.join(',')})" ) do |row| db_mycard.execute( "select id, number from `yu-gi-oh` where number in (#{(@images+@thumbnails).uniq.collect{|number|"'%08d'" % number}.join(',')})" ) do |row|
id = row[0] id = row[0]
number = row[1].to_i number = row[1].to_i
src = "#{Card::PicPath}/#{id}.jpg"
dest = "ygocore/pics/#{number}.jpg"
dest_thumb = "ygocore/pics/thumbnail/#{number}.jpg"
if File.file?(src)
@status.replace "检测到存在iDuel卡图 正在导入 #{id}.jpg"
existed_images << number existed_images << number
src = "#{Card::PicPath}/#{id}.jpg" if !File.exist?(dest)
dest = "ygocore/pics/#{number}.jpg" FileUtils.copy_file(src, dest)
dest_thumb = "ygocore/pics/thumbnail/#{number}.jpg" FileUtils.copy_file(src, dest_thumb)
if File.file?(src)
@status.replace "检测到存在iDuel卡图 正在导入 #{id}.jpg"
if !File.exist?(dest)
if can_link
File.link(src, dest) rescue can_link = false
end
if !can_link
FileUtils.copy_file(src, dest)
end
if !File.exist?(dest_thumb)
if internal_can_link
File.link(dest, dest_thumb) rescue internal_can_link = false
end
if !internal_can_link
FileUtils.copy_file(dest, dest_thumb)
end
end
elsif !File.exist?(dest_thumb)
if can_link
File.link(src, dest_thumb) rescue can_link = false
end
if !can_link
FileUtils.copy_file(src, dest_thumb)
end
end
end end
end end
end end
@images -= existed_images end
@thumbnails -= existed_images @images -= existed_images
@thumbnails = (@thumbnails & @images) + (@thumbnails - @images) @thumbnails -= existed_images
unless @thumbnails.empty? and @images.empty? @thumbnails = (@thumbnails & @images) + (@thumbnails - @images)
$log.info('待下载的完整卡图'){@images.inspect} unless @thumbnails.empty? and @images.empty?
threads = 5.times.collect do $log.info('待下载的完整卡图'){@images.inspect}
thread = Thread.new do $log.info('待下载的缩略卡图'){@thumbnails.inspect}
while number = @thumbnails.pop threads = 5.times.collect do
@status.replace "正在下载缩略卡图 (剩余#{@thumbnails.size}张)" thread = Thread.new do
open("http://card.touhou.cc/images/cards/ygocore/thumbnail/#{number}.jpg", 'rb') do |remote| while number = @thumbnails.pop
next if File.file? "ygocore/pics/thumbnail/#{number}.jpg" @status.replace "正在下载缩略卡图 (剩余#{@thumbnails.size}张)"
open("ygocore/pics/thumbnail/#{number}.jpg", 'wb') do |local| open("http://card.touhou.cc/images/cards/ygocore/thumbnail/#{number}.jpg", 'rb') do |remote|
local.write remote.read next if File.file? "ygocore/pics/thumbnail/#{number}.jpg"
end #$log.debug('下载缩略卡图'){"http://card.touhou.cc/images/cards/ygocore/thumbnail/#{number}.jpg 到 ygocore/pics/thumbnail/#{number}.jpg" }
end rescue nil open("ygocore/pics/thumbnail/#{number}.jpg", 'wb') do |local|
end local.write remote.read
while number = @images.pop end
@status.replace "正在下载完整卡图 (剩余#{@images.size}张)" end rescue $log.error('下载缩略出错'){"http://card.touhou.cc/images/cards/ygocore/thumbnail/#{number}.jpg 到 ygocore/pics/thumbnail/#{number}.jpg" }
open("http://card.touhou.cc/images/cards/ygocore/#{number}.jpg", 'rb') do |remote|
next if File.file? "ygocore/pics/#{number}.jpg"
open("ygocore/pics/#{number}.jpg", 'wb') do |local|
local.write remote.read
end
end rescue nil
end
end end
thread.priority = -1 while number = @images.pop
thread @status.replace "正在下载完整卡图 (剩余#{@images.size}张)"
#$log.debug('下载完整卡图'){"http://card.touhou.cc/images/cards/ygocore/#{number}.jpg 到 ygocore/pics/#{number}.jpg" }
open("http://card.touhou.cc/images/cards/ygocore/#{number}.jpg", 'rb') do |remote|
next if File.file? "ygocore/pics/#{number}.jpg"
open("ygocore/pics/#{number}.jpg", 'wb') do |local|
local.write remote.read
end
end rescue $log.error('下载完整卡图出错'){"http://card.touhou.cc/images/cards/ygocore/#{number}.jpg 到 ygocore/pics/#{number}.jpg" }
end
end end
threads.each{|thread|thread.join} thread.priority = -1
thread
end end
threads.each{|thread|thread.join}
end end
end rescue nil end rescue $log.error('卡图更新'){'找不到ygocore卡片数据库'}
@status = nil @status = nil
end.priority = -1 end.priority = -1
end end
def copy(src, dest, can_link)
if can_link
File.link(src, dest)
else
open(src, 'rb') do |src|
open(dest, 'wb') do |dest|
dest.write src.read
end
end
end
end
end end
end end
\ No newline at end of file
...@@ -76,11 +76,11 @@ module RM_IME ...@@ -76,11 +76,11 @@ module RM_IME
module_function module_function
def init def init
return if @active return if @active
$log.info('输入法'){'开启'}
_init(HWND, 0, 0) _init(HWND, 0, 0)
@x = 0 @x = 0
@y = 0 @y = 0
@active = true @active = true
$log.info('输入法'){'开启'}
end end
def set(x,y) def set(x,y)
@x = x @x = x
...@@ -102,8 +102,8 @@ module RM_IME ...@@ -102,8 +102,8 @@ module RM_IME
end end
def dispose def dispose
return if !@active return if !@active
_dispose
$log.info('输入法'){'关闭'} $log.info('输入法'){'关闭'}
_dispose
@active = false @active = false
end end
def active? def active?
......
...@@ -24,10 +24,12 @@ class Window_Chat < Window_Scrollable ...@@ -24,10 +24,12 @@ class Window_Chat < Window_Scrollable
@chat_input = Widget_InputBox.new(@x+8, @y+@height-24-10, @width-14, 24) do |key| @chat_input = Widget_InputBox.new(@x+8, @y+@height-24-10, @width-14, 24) do |key|
case key case key
when :ENTER when :ENTER
chatmessage = ChatMessage.new($game.user, @chat_input.value, @channel) if !@chat_input.value.empty?
$game.chat chatmessage chatmessage = ChatMessage.new($game.user, @chat_input.value, @channel)
Game_Event.push Game_Event::Chat.new(chatmessage) $game.chat chatmessage
true Game_Event.push Game_Event::Chat.new(chatmessage)
true
end
when :ESC when :ESC
true true
end end
...@@ -48,7 +50,10 @@ class Window_Chat < Window_Scrollable ...@@ -48,7 +50,10 @@ class Window_Chat < Window_Scrollable
end end
def add(chatmessage) def add(chatmessage)
@@list[chatmessage.channel] ||= [] @@list[chatmessage.channel] ||= []
@channels << chatmessage.channel unless @channels.include? chatmessage.channel unless @channels.include? chatmessage.channel
@channels << chatmessage.channel
refresh
end
@@list[chatmessage.channel] << chatmessage @@list[chatmessage.channel] << chatmessage
scroll_bottom = @items.size - self.scroll <= @page_size scroll_bottom = @items.size - self.scroll <= @page_size
add_split(chatmessage) add_split(chatmessage)
......
...@@ -2,8 +2,8 @@ class Window_Host < Window ...@@ -2,8 +2,8 @@ class Window_Host < Window
attr_reader :index attr_reader :index
def initialize(x,y) def initialize(x,y)
@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 => [46,110,@button.w/3,@button.h], :cancel => [156,110,@button.w/3, @button.h]}
@buttons = {:ok => "确定"} @buttons = {:ok => "确定", :cancel => "取消"}
@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) super((1024-@background.w)/2, 230, @background.w, @background.h)
@font = TTF.open("fonts/wqy-microhei.ttc", 16) @font = TTF.open("fonts/wqy-microhei.ttc", 16)
...@@ -18,13 +18,7 @@ class Window_Host < Window ...@@ -18,13 +18,7 @@ class Window_Host < Window
true true
end end
end end
default_name = $game.user.name @roomname_inputbox.value = rand(1000).to_s
1.upto(1000) do |i|
if $game.rooms.all?{|room|room.name != i.to_s}
break default_name = i.to_s
end
end
@roomname_inputbox.value = default_name
@pvp = Widget_Checkbox.new(self, 33+@x,70+@y,120,24,false,"竞技场") @pvp = Widget_Checkbox.new(self, 33+@x,70+@y,120,24,false,"竞技场")
@pvp.background = @background.copy_rect(33,70,120,24) @pvp.background = @background.copy_rect(33,70,120,24)
@match = Widget_Checkbox.new(self, 120+@x,70+@y,120,24,true,"三回决斗") @match = Widget_Checkbox.new(self, 120+@x,70+@y,120,24,true,"三回决斗")
...@@ -37,7 +31,9 @@ class Window_Host < Window ...@@ -37,7 +31,9 @@ class Window_Host < Window
clear clear
@font.draw_blended_utf8(@contents, "新房间", (@width-@font.text_size("新房间")[0])/2, 2, *@title_color) @font.draw_blended_utf8(@contents, "新房间", (@width-@font.text_size("新房间")[0])/2, 2, *@title_color)
@font.draw_blended_utf8(@contents, "房间名", 33,43, *@color) @font.draw_blended_utf8(@contents, "房间名", 33,43, *@color)
draw_item(:ok, self.index==:ok ? 1 : 0) @items.each_key do |index|
draw_item(index, self.index==index ? 1 : 0)
end
end end
def draw_item(index, status=0) def draw_item(index, status=0)
Surface.blit(@button,@button.w/3*status,0,@button.w/3,@button.h,@contents,@items[index][0],@items[index][1]) Surface.blit(@button,@button.w/3*status,0,@button.w/3,@button.h,@contents,@items[index][0],@items[index][1])
...@@ -45,17 +41,23 @@ class Window_Host < Window ...@@ -45,17 +41,23 @@ class Window_Host < Window
@font.draw_blended_utf8(@contents, @buttons[index], @items[index][0]+(@button.w/3-text_size[0])/2, @items[index][1]+(@button.h-text_size[1])/2, 0xFF, 0xFF, 0xFF) @font.draw_blended_utf8(@contents, @buttons[index], @items[index][0]+(@button.w/3-text_size[0])/2, @items[index][1]+(@button.h-text_size[1])/2, 0xFF, 0xFF, 0xFF)
end end
def mousemoved(x,y) def mousemoved(x,y)
if (x - @x).between?(@items[:ok][0], @items[:ok][0]+@items[:ok][2]) and (y-@y).between?(@items[:ok][1], @items[:ok][1]+@items[:ok][3]) new_index = nil
self.index = :ok @items.each_key do |index|
else if (x - @x).between?(@items[index][0], @items[index][0]+@items[index][2]) and (y-@y).between?(@items[index][1], @items[index][1]+@items[index][3])
self.index = nil new_index = index
break
end
end end
self.index = new_index
end
def item_rect(index)
@items[index]
end end
def index=(index) def index=(index)
return if index == @index return if index == @index
if @index if @index
#clear(*item_rect(@index)) clear(*item_rect(@index))
draw_item(@index, 0) draw_item(@index, 0)
end end
if index.nil? or !@items.include? index if index.nil? or !@items.include? index
...@@ -72,6 +74,8 @@ class Window_Host < Window ...@@ -72,6 +74,8 @@ class Window_Host < Window
@joinroom_msgbox = Widget_Msgbox.new("建立房间", "正在建立房间") @joinroom_msgbox = Widget_Msgbox.new("建立房间", "正在建立房间")
destroy destroy
$game.host(@roomname_inputbox.value, :pvp => @pvp.checked?, :match => @match.checked?) $game.host(@roomname_inputbox.value, :pvp => @pvp.checked?, :match => @match.checked?)
when :cancel
destroy
end end
end end
def destroy def destroy
......
require_relative 'window_host' require_relative 'window_host'
class Window_LobbyButtons < Window_List class Window_LobbyButtons < Window_List
def initialize(x,y) def initialize(x,y)
super(x,y,86,30) @items = ["卡组编辑","建立房间"]
@items = ["新房间"]
@button = Surface.load("graphics/lobby/button.png") @button = Surface.load("graphics/lobby/button.png")
@font = TTF.open("fonts/wqy-microhei.ttc", 16) super(x,y,@items.size*@button.w/3+@items.size*4,30)
@font = TTF.open("fonts/wqy-microhei.ttc", 15)
refresh refresh
end end
def draw_item(index, status=0) def draw_item(index, status=0)
Surface.blit(@button, status*@button.w/3,0,@button.w/3,@button.h, @contents, 0, 0) x,y=item_rect(index)
@font.draw_blended_utf8(@contents,"新房间",16,5,20,10,180) Surface.blit(@button, status*@button.w/3,0,@button.w/3,@button.h, @contents, x,y)
draw_stroked_text(@items[index], x+8,y+3,2,@font,[0xdf,0xf1,0xff], [0x27,0x43,0x59])
end
def item_rect(index)
[index*@button.w/3+(index)*4, 0, @button.w/3, @height]
end end
def mousemoved(x,y) def mousemoved(x,y)
self.index = 0 if (x-@x) % (@button.w/3+4) >= @button.w/3
self.index = nil
else
self.index = (x-@x)/(@button.w/3+4)
end
end end
def lostfocus(active_window = nil) def lostfocus(active_window = nil)
self.index = nil self.index = nil
end end
def clicked def clicked
@host_window = Window_Host.new(300,200) case @index
when 0 #卡组编辑
$game.class.deck_edit
when 1 #建立房间
@host_window = Window_Host.new(300,200)
end
end end
def update def update
@host_window.update if @host_window and !@host_window.destroyed? @host_window.update if @host_window and !@host_window.destroyed?
......
...@@ -45,9 +45,9 @@ class Window_Login < Window ...@@ -45,9 +45,9 @@ class Window_Login < Window
:replay => [378,200,@button.w/3,@button.h] :replay => [378,200,@button.w/3,@button.h]
} }
@items_text = { @items_text = {
:login => "登", :login => "登",
:register => "注册", :register => "注册",
:replay => "战报" :replay => "录像"
} }
#self.index = nil #self.index = nil
@remember_password = Widget_Checkbox.new(self, 357+@x,80+@y,self.width-357,24,password,"记住密码") @remember_password = Widget_Checkbox.new(self, 357+@x,80+@y,self.width-357,24,password,"记住密码")
......
...@@ -6,7 +6,7 @@ class Window_User < Window_List ...@@ -6,7 +6,7 @@ class Window_User < Window_List
@font = TTF.open('fonts/wqy-microhei.ttc', 16) @font = TTF.open('fonts/wqy-microhei.ttc', 16)
@user = user @user = user
@contents = Surface.load("graphics/lobby/user.png").display_format #TODO:调用已经加载了的背景 @contents = Surface.load("graphics/lobby/user.png").display_format #TODO:调用已经加载了的背景
@close = Surface.load("graphics/lobby/userclose.png")
@avatar_boarder = Surface.load("graphics/lobby/avatar_boader.png") @avatar_boarder = Surface.load("graphics/lobby/avatar_boader.png")
@items = ["发送消息", "查看资料"] @items = ["发送消息", "查看资料"]
@items << "加入游戏" if user.status == :waiting @items << "加入游戏" if user.status == :waiting
...@@ -25,7 +25,8 @@ class Window_User < Window_List ...@@ -25,7 +25,8 @@ class Window_User < Window_List
@font.draw_blended_utf8(@contents, @user.name, 172, 24, 0x00,0x00,0x00) @font.draw_blended_utf8(@contents, @user.name, 172, 24, 0x00,0x00,0x00)
@font.draw_blended_utf8(@contents, "id: #{@user.id}" , 172, 32+WLH, 0x00,0x00,0x00) @font.draw_blended_utf8(@contents, "id: #{@user.id}" , 172, 32+WLH, 0x00,0x00,0x00)
@font.draw_blended_utf8(@contents, "#{'房间' + @user.room.id.to_s + ' ' if @user.room}#{case @user.status;when :lobby;'大厅';when :dueling;'决斗中';when :waiting;'等待中';end}", 172, 32+WLH*2, 0x00,0x00,0x00) @font.draw_blended_utf8(@contents, "#{'房间' + @user.room.id.to_s + '' if @user.room}#{case @user.status;when :lobby;'大厅';when :dueling;'决斗中';when :waiting;'等待中';end}", 172, 32+WLH*2, 0x00,0x00,0x00)
Surface.blit(@close, 0, 0, @close.w/3, @close.h, @contents, @width-24,10)
end end
def clear(x=0,y=0,width=@width,height=@height) def clear(x=0,y=0,width=@width,height=@height)
......
class Game_Event class Game_Event
User_Filter = /\[(\d+),(.+?)(?:,(-1|0)|)\]/ def self.parse(header, data)
Room_Filter = /\[(\d+),(.+?),(wait|start)(#{User_Filter}+?)\]/ case header
#User_Filter = /<li>(:::观战:|===决斗1=|===决斗2=)<font color="(?:blue|gray)">(.+?)(\(未认证\)|)<\/font>;<\/li>/ when :login
#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>/ if data
class AllRooms < Game_Event Login.new User.new(data[:id], data[:name])
def self.notify_send(title, msg) else
command = "notify-send -i graphics/system/icon.ico #{title} #{msg}" Error.new('登录', '用户名或密码错误')
command = "start ruby/bin/#{command}".encode "GBK" if RUBY_PLATFORM["win"] || RUBY_PLATFORM["ming"]
system(command)
$log.info command
end
def self.parse(info)
@rooms = []
info.scan(Room_Filter) do |id, name, status, users|
#p id, name, status, users, '------------'
player1 = player2 = nil
users.scan(User_Filter) do |player, name, certified|
if name =~ /^<font color="(?:blue|gray)">(.+?)<\/font>$/
name = $1
end
if certified == '0'
certified = false
elsif name =~ /^(.+?)\(未认证\)$/
name = $1
certified = false
else
certified = true
end
if player["1"]
player1 = User.new(name.to_sym, name, certified)
elsif player["2"]
player2 = User.new(name.to_sym, name, certified)
end
end
if player1 == $game.user or player2 == $game.user
$game.room = Room.new(id.to_i, name)
end
if $game.room and id.to_i == $game.room.id and (($game.room.player1.nil? and player1 and player1 != $game.user) or ($game.room.player2.nil? and player2 and player2 != $game.user))
@@join_se ||= Mixer::Wave.load("audio/se/join.ogg")
Mixer.play_channel(-1,@@join_se,0)
if $game.room.player1.nil? and player1 and player1 != $game.user
player = player1
elsif $game.room.player2.nil? and player2 and player2 != $game.user
player = player2
end
notify_send("对手加入房间", "#{player.name}(#{player.id})")
end
room = Room.new(id.to_i, name, player1, player2, false, [0,0,0])
room.status = status.to_sym
room.name =~ /^(P)?(M)?\#?(.*?)(?:<font color="d28311" title="竞技场模式">\[竞\]<\/font>)?$/
room.name = $3
room.pvp = !!$1
room.match = !!$2
if status == "wait"
@rooms.unshift room
else
@rooms << room
end
end end
self.new @rooms when :users
end AllUsers.new data.collect{|user|User.new(user[:id], user[:name], user[:certified])}
end when :rooms
class AllUsers < Game_Event AllRooms.new data.collect{|room|
def self.parse(info) result = Room.new(room[:id], room[:name])
@users = [] result.player1 = room[:player1] && User.new(room[:player1][:id], room[:player1][:name])
$game.rooms.each do |room| result.player2 = room[:player2] && User.new(room[:player2][:id], room[:player2][:name])
@users << room.player1 if room.player1 result.pvp = room[:pvp]
@users << room.player2 if room.player2 result.match = room[:match]
result.status = room[:status]
result
}.sort_by{|room|room.full? ? 1 : 0}
when :chat
case data[:channel]
when :lobby
Chat.new ChatMessage.new User.new(data[:from][:id],data[:from][:name]), data[:message], :lobby
else
Chat.new ChatMessage.new User.new(data[:from][:id],data[:from][:name]), data[:message], User.new(data[:channel])
end end
self.new @users
end
end
class Join < Game_Event
def initialize(room)
@room = room
$game.room = @room
end end
end end
end end
\ No newline at end of file
#encoding: UTF-8 #encoding: UTF-8
load 'lib/ygocore/window_login.rb' load 'lib/ygocore/window_login.rb'
require 'eventmachine'
require 'open-uri'
class Ygocore < Game class Ygocore < Game
attr_reader :username
attr_reader :password attr_reader :password
@@config = YAML.load_file("lib/ygocore/server.yml") @@config = YAML.load_file("lib/ygocore/server.yml")
def initialize def initialize
...@@ -12,104 +15,54 @@ class Ygocore < Game ...@@ -12,104 +15,54 @@ class Ygocore < Game
require 'json' require 'json'
end end
def login(username, password) def login(username, password)
if username.empty? @username = username
return Widget_Msgbox.new("登陆", "请输入用户名", :ok => "确定") @password = password
connect
end
def connect
@recv = Thread.new do
EventMachine::run {
EventMachine::connect "card.touhou.cc", 9998, Client
}
end end
if password.empty? end
Widget_Msgbox.new("登陆", "无密码登陆,不能建房,不能加入竞技场", :ok => "确定"){Game_Event.push Game_Event::Login.new(User.new(username.to_sym, username))} def chat(chatmessage)
else case chatmessage.channel
require 'cgi' when :lobby
result = open("#{@@config['api']}?operation=passcheck&username=#{CGI.escape username}&pass=#{CGI.escape password}") do |file| send(:chat, channel: :lobby, message: chatmessage.message, time: chatmessage.time)
file.set_encoding "GBK" when User
result = file.read.encode("UTF-8") send(:chat, channel: chatmessage.channel.id, message: chatmessage.message, time: chatmessage.time)
$log.info('用户登陆传回消息'){result}
result
end rescue nil
case result
when "true"
connect
@password = password
Game_Event.push Game_Event::Login.new(User.new(username.to_sym, username))
when "false"
Game_Event.push Game_Event::Error.new("登陆", "用户名或密码错误", false)
else
Widget_Msgbox.new("登陆", "连接服务器失败", :ok => "确定")
end
end end
end end
def host(room_name, room_config) def host(room_name, room_config)
if $game.password.nil? or $game.password.empty?
return Widget_Msgbox.new("建立房间", "必须有账号才能建立房间", :ok => "确定")
end
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]
refresh do if $game.rooms.any?{|game_room|game_room.name == room_name}
if $game.rooms.any?{|game_room|game_room.name == room_name} Widget_Msgbox.new("建立房间", "房间名已存在", :ok => "确定")
Widget_Msgbox.new("建立房间", "房间名已存在", :ok => "确定") else
else Game_Event.push Game_Event::Join.new(room)
if !Update.images.empty?
Widget_Msgbox.new("加入房间", "卡图正在下载中,可能显示不出部分卡图", :ok => "确定"){Game_Event.push Game_Event::Join.new(room)}
else
Game_Event.push Game_Event::Join.new(room)
end
end
end end
end end
def watch(room) def watch(room)
Widget_Msgbox.new("加入房间", "游戏已经开始", :ok => "确定") Widget_Msgbox.new("加入房间", "游戏已经开始", :ok => "确定")
end end
def join(room) def join(room)
if $game.password.nil? or $game.password.empty? and room.pvp? Game_Event.push Game_Event::Join.new(room)
return Widget_Msgbox.new("加入房间", "必须有账号才能加入竞技场房间", :ok => "确定")
end
if !ygocore_path
return Widget_Msgbox.destroy
end
refresh do
if room.full? #如果游戏已经开了
Widget_Msgbox.new("加入房间", "游戏已经开始", :ok => "确定")
elsif !$game.rooms.include? room
Widget_Msgbox.new("加入房间", "游戏已经取消", :ok => "确定")
else
if !Update.images.empty?
Widget_Msgbox.new("加入房间", "卡图正在下载中,可能出现显示不出卡图", :ok => "确定"){Game_Event.push Game_Event::Join.new(room)}
else
Game_Event.push Game_Event::Join.new(room)
end
end
end
end end
def refresh def refresh
$log.info('刷新大厅信息'){'开始'} send(:refresh)
Thread.new do end
begin def send(header, data=nil)
open("#{@@config['api']}?operation=getroom") do |file| $log.info('发送消息'){ {header: header, data: data}}
file.set_encoding("GBK") Client::MycardChannel.push header: header, data: data
info = file.read.encode("UTF-8") end
$log.info('刷新大厅信息'){'完成'} def exit
Game_Event.push Game_Event::AllRooms.parse info @recv.exit if @recv
Game_Event.push Game_Event::AllUsers.parse info @recv = nil
yield if block_given?
end
rescue Exception => exception
$log.warn('刷新大厅'){[exception.inspect, *exception.backtrace].collect{|str|str.encode("UTF-8")}.join("\n")}
end
end
end end
def ygocore_path def 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 #防止重复点击
# msgbox = Widget_Msgbox.new("加入房间", "请指定ygocore主程序位置")
# $scene.draw
# require_relative '../dialog'
# $config['ygocore']['path'] = Dialog.get_open_file("请指定ygocore主程序位置","ygocore主程序 (gframe.exe)" => "gframe.exe")
# save_config
# msgbox.destroy
# @last_clicked = Time.now
"ygocore/gframe.exe" "ygocore/gframe.exe"
end end
def self.register def self.register
...@@ -121,7 +74,10 @@ class Ygocore < Game ...@@ -121,7 +74,10 @@ class Ygocore < Game
def port def port
@@config['port'] @@config['port']
end end
def self.run_ygocore(option) def self.run_ygocore(option, image_downloading=false)
if !image_downloading and !Update.images.empty?
return Widget_Msgbox.new("加入房间", "卡图正在下载中,可能显示不出部分卡图", :ok => "确定"){run_ygocore(option, true)}
end
path = 'ygocore/gframe.exe' path = 'ygocore/gframe.exe'
Widget_Msgbox.new("ygocore", "正在启动ygocore") Widget_Msgbox.new("ygocore", "正在启动ygocore")
#写入配置文件并运行ygocore #写入配置文件并运行ygocore
...@@ -171,17 +127,39 @@ class Ygocore < Game ...@@ -171,17 +127,39 @@ class Ygocore < Game
end end
Widget_Msgbox.destroy Widget_Msgbox.destroy
end end
private def self.deck_edit
def connect Widget_Msgbox.new("编辑卡组", "\"导入\"导入已有卡组,\"编辑\"启动ygocore", :import => "导入", :edit => "编辑") do |button|
require 'open-uri' case button
when:import
file = Dialog.get_open_file("导入卡组", "ygocore卡组 (*.ydk)"=>"*.ydk")#"所有支持的卡组 (*.txt;*.deck;*.ydk)"=>"*.ydk;*.txt;*.deck","ygocore卡组 (*.ydk)"=>"*.ydk", "NBX/iDuel/狐查卡组 (*.txt)" => "*.txt", "图形组卡器卡组 (*.deck)"=>"*.deck")
if !file.empty?
open(file) do |src|
Dir.mkdir "ygocore/deck" unless File.directory?("ygocore/deck")
open("ygocore/deck/#{File.basename(file)}", 'w') do |dest|
dest.write src.read
end
Widget_Msgbox.new("导入卡组", "导入卡组完成", :ok => "确定")
end rescue Widget_Msgbox.new("导入卡组", "导入卡组失败", :ok => "确定")
end
when :edit
Ygocore.run_ygocore(:deck)
end
end
end
def self.replay(file)
require 'fileutils'
FileUtils.mv Dir.glob('ygocore/replay/*.yrp'), 'replay/'
FileUtils.copy_file(file, "ygocore/replay/#{File.basename(file)}")
run_ygocore(:replay)
end end
private
def self.get_announcements def self.get_announcements
#公告 #公告
$config['ygocore'] ||= {} $config['ygocore'] ||= {}
$config['ygocore']['announcements'] ||= [Announcement.new("正在读取公告...", nil, nil)] $config['ygocore']['announcements'] ||= [Announcement.new("正在读取公告...", nil, nil)]
Thread.new do Thread.new do
begin begin
require 'open-uri'
open(@@config['api']) do |file| open(@@config['api']) do |file|
file.set_encoding "GBK" file.set_encoding "GBK"
announcements = [] announcements = []
...@@ -196,9 +174,20 @@ class Ygocore < Game ...@@ -196,9 +174,20 @@ class Ygocore < Game
end end
end end
end end
module Client
MycardChannel = EM::Channel.new
include EM::P::ObjectProtocol
def post_init
send_object header: :login, data: {name: $game.username, password: $game.password}
MycardChannel.subscribe{|msg|send_object(msg)}
end
def receive_object obj
$log.info('收到消息'){obj.inspect}
Game_Event.push Game_Event.parse obj[:header], obj[:data]
end
def unbind
Game_Event.push Game_Event::Error.new('ygocore', '网络连接中断', true)
end
end
get_announcements get_announcements
end
def MAKELPARAM(w1,w2)
(w2<<16) | w1
end end
\ No newline at end of file
class Room class Room
attr_accessor :pvp attr_accessor :pvp
attr_accessor :match attr_accessor :match
attr_writer :status attr_accessor :status
alias pvp? pvp alias pvp? pvp
alias match? match alias match? match
def full? def full?
......
class User class User
attr_reader :certified
def initialize(id, name = "", certified = true) def initialize(id, name = "", certified = true)
@id = id @id = id
@name = name @name = name
...@@ -13,6 +14,25 @@ class User ...@@ -13,6 +14,25 @@ class User
@certified ? [0,0,0] : [128,128,128] @certified ? [0,0,0] : [128,128,128]
end end
def space def space
Widget_Msgbox.new("查看资料", "功能未实现", :ok => "确定") if @certified
system("start http://card.touhou.cc/users/#{CGI.escape @id.to_s}")
else
Widget_Msgbox.new("查看资料", "用户#{@name}没有注册", :ok => "确定")
end
end
def avatar(size = :small)
cache = "graphics/avatars/mycard_#{@id}_#{size}.png"
result = Surface.load(cache) rescue Surface.load("graphics/avatars/loading_#{size}.gif")
scene = $scene
if block_given?
yield result
Thread.new do
require 'cgi'
open("http://card.touhou.cc/users/#{CGI.escape @id.to_s}.png", 'rb') {|io|open(cache, 'wb') {|c|c.write io.read}} rescue cache = "graphics/avatars/noavatar_#{size}.gif"
(yield Surface.load(cache) if scene == $scene) rescue nil
end
else
result
end
end end
end end
...@@ -3,7 +3,7 @@ class Window_Login ...@@ -3,7 +3,7 @@ class Window_Login
return if @last_clicked and Time.now - @last_clicked < 3 #防止重复点击 return if @last_clicked and Time.now - @last_clicked < 3 #防止重复点击
case @index case @index
when :login when :login
Widget_Msgbox.new("ygocore", "正在登") Widget_Msgbox.new("ygocore", "正在登")
$scene.draw #强制重绘一次,下面会阻塞 $scene.draw #强制重绘一次,下面会阻塞
$game = Ygocore.new $game = Ygocore.new
$config[$config['game']]['username'] = @username_inputbox.value $config[$config['game']]['username'] = @username_inputbox.value
...@@ -14,18 +14,12 @@ class Window_Login ...@@ -14,18 +14,12 @@ class Window_Login
when :register when :register
Ygocore.register Ygocore.register
@last_clicked = Time.now @last_clicked = Time.now
#when :replay when :replay
# require 'tk' file = Dialog.get_open_file("播放录像", "ygocore录像 (*.yrp)" => "*.yrp")
# file = Tk.getOpenFile if !file.empty? and File.file? file
# if !file.empty? Ygocore.replay file
# $game = Iduel.new end
# $game.user = User.new(0) @last_clicked = Time.now
# Widget_Msgbox.new("回放战报", "战报读取中...")
# $scene.draw
# $log.debug('iduel window_login'){'loading reply file'}
# $scene = Scene_Replay.new Replay.load file
# end
# @last_clicked = Time.now
end end
end end
end end
\ 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