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

nothing

parent c1f6f124
/nbproject/ /nbproject/
/.idea/ /.idea/
/ruby/ /ruby/
/pkg/ /pkg/
/config.yml /config.yml
/log.log /log.log
/profile.log /profile.log
/replay/ /replay/
/mycard/ /mycard/
/mycard.exe /mycard.exe
/7z.exe /7z.exe
/ygocore/ /ygocore/
/graphics/avatars/*_*.png /graphics/avatars/*_*.png
/error-程序出错请到论坛反馈.txt /error-程序出错请到论坛反馈.txt
Thumbs.db Thumbs.db
\ No newline at end of file
#encoding: UTF-8 #encoding: UTF-8
require 'rubygems' require 'rubygems'
require 'rake' require 'rake'
require 'rake/clean' require 'rake/clean'
require 'rubygems/package_task' require 'rubygems/package_task'
require 'rdoc/task' require 'rdoc/task'
#require 'rake/testtask' #require 'rake/testtask'
Windows = RUBY_PLATFORM["mingw"] || RUBY_PLATFORM["mswin"] Windows = RUBY_PLATFORM["mingw"] || RUBY_PLATFORM["mswin"]
#在windows上UTF-8脚本编码环境中 Dir.glob无法列出中文目录下的文件 所以自己写个递归 #在windows上UTF-8脚本编码环境中 Dir.glob无法列出中文目录下的文件 所以自己写个递归
def list(path) def list(path)
result = [] result = []
Dir.foreach(path) do |file| Dir.foreach(path) do |file|
next if file == "." or file == ".." next if file == "." or file == ".."
result << "#{path}/#{file}" result << "#{path}/#{file}"
result.concat list(result.last) if File.directory? result.last result.concat list(result.last) if File.directory? result.last
end end
result result
end end
spec = Gem::Specification.new do |s| spec = Gem::Specification.new do |s|
s.name = 'mycard' s.name = 'mycard'
s.version = '0.7.4' s.version = '0.7.4'
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
s.author = 'zh99998' s.author = 'zh99998'
s.email = 'zh99998@gmail.com' s.email = 'zh99998@gmail.com'
s.homepage = 'http://card.touhou,cc' s.homepage = 'http://card.touhou,cc'
# s.executables = ['your_executable_here'] # s.executables = ['your_executable_here']
s.files = %w(LICENSE.txt README.txt replay) s.files = %w(LICENSE.txt README.txt replay)
%w{lib audio data fonts graphics ygocore}.each{|dir|s.files.concat list(dir)} %w{lib audio data fonts graphics ygocore}.each{|dir|s.files.concat list(dir)}
if Windows if Windows
s.files += %w(mycard.exe) + list("ruby") s.files += %w(mycard.exe) + list("ruby")
else else
s.files += %w(install.sh) s.files += %w(install.sh)
end end
s.require_path = "lib" s.require_path = "lib"
#s.bindir = "bin" #s.bindir = "bin"
end end
Gem::PackageTask.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
p.zip_command = '../7z.exe a' p.zip_command = '../7z.exe a'
def p.zip_file def p.zip_file
"#{package_name}-win32.7z" "#{package_name}-win32.7z"
end end
else else
p.need_tar = true p.need_tar = true
end end
end end
Rake::RDocTask.new do |rdoc| Rake::RDocTask.new do |rdoc|
files =['README.txt', 'LICENSE.txt', 'lib/**/*.rb'] files =['README.txt', 'LICENSE.txt', 'lib/**/*.rb']
rdoc.rdoc_files.add(files) rdoc.rdoc_files.add(files)
rdoc.main = "README.txt" # page to start on rdoc.main = "README.txt" # page to start on
rdoc.title = "Mycard Docs" rdoc.title = "Mycard Docs"
rdoc.rdoc_dir = 'doc/rdoc' # rdoc output folder rdoc.rdoc_dir = 'doc/rdoc' # rdoc output folder
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/} + list("ygocore/deck").keep_if{|file|File.basename(file) != 'sample.ydk'} 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'}
--- ---
name: "沙沙" name: "沙沙"
field: field:
cardimage: cardimage:
- 1 - 1
- 2 - 2
- 3 - 3
- 4 - 4
cardtext: cardtext:
- 5 - 5
- 6 - 6
- 7 - 7
- 8 - 8
chat: chat:
- 9 - 9
- 10 - 10
- 11 - 11
- 12 - 12
#encoding: UTF-8 #encoding: UTF-8
class Action class Action
attr_accessor :from_player, :msg attr_accessor :from_player, :msg
attr_accessor :id attr_accessor :id
def initialize(from_player=true, msg=nil) def initialize(from_player=true, msg=nil)
@id = @@id @id = @@id
@from_player = from_player @from_player = from_player
@msg = msg @msg = msg
@@id += 1 if @from_player @@id += 1 if @from_player
end end
def player_field def player_field
@from_player ? $game.player_field : $game.opponent_field @from_player ? $game.player_field : $game.opponent_field
end end
def opponent_field def opponent_field
@from_player ? $game.opponent_field : $game.player_field @from_player ? $game.opponent_field : $game.player_field
end end
def run def run
#子类定义 #子类定义
end end
class Reset < Action class Reset < Action
def run def run
player_field.reset player_field.reset
super super
end end
end end
class Deck < Action; end class Deck < Action; end
class Side < Deck; end class Side < Deck; end
class Go < Reset class Go < Reset
def run def run
super super
player_field.hand = player_field.deck.pop(5) player_field.hand = player_field.deck.pop(5)
end end
end end
class FirstToGo < Go; end class FirstToGo < Go; end
class SecondToGo < Go; end class SecondToGo < Go; end
class Chat < Action; end class Chat < Action; end
class Shuffle < Action class Shuffle < Action
def run def run
player_field.deck.shuffle! player_field.deck.shuffle!
super super
end end
end end
class Coin < Action class Coin < Action
attr_reader :result attr_reader :result
def initialize(from_player, result=rand(1)==0, msg=nil) def initialize(from_player, result=rand(1)==0, msg=nil)
super(from_player, msg) super(from_player, msg)
@result = result @result = result
end end
end end
class Dice < Action class Dice < Action
attr_reader :result attr_reader :result
def initialize(from_player, result=rand(6)+1, msg=nil) def initialize(from_player, result=rand(6)+1, msg=nil)
super(from_player, msg) super(from_player, msg)
@result = result @result = result
end end
end end
class ChangePhase < Action class ChangePhase < Action
attr_reader :phase attr_reader :phase
def initialize(from_player, phase) def initialize(from_player, phase)
super(from_player) super(from_player)
@phase = phase @phase = phase
end end
def run def run
$game.phase = phase $game.phase = phase
super super
end end
end end
class Move < Action class Move < Action
attr_reader :from_pos, :to_pos, :card, :position attr_reader :from_pos, :to_pos, :card, :position
def initialize(from_player, from_pos, to_pos=nil, card=nil, msg=nil, position=nil) def initialize(from_player, from_pos, to_pos=nil, card=nil, msg=nil, position=nil)
super(from_player, msg) super(from_player, msg)
@from_pos = from_pos @from_pos = from_pos
@to_pos = to_pos @to_pos = to_pos
@card = card @card = card
@position = position @position = position
end end
def parse_field(pos) def parse_field(pos)
case pos case pos
when 0..10, :field when 0..10, :field
player_field.field player_field.field
when 11..70, :hand, :handtop, :handrandom when 11..70, :hand, :handtop, :handrandom
player_field.hand player_field.hand
when 71..130,:deck, :decktop, :deckbottom when 71..130,:deck, :decktop, :deckbottom
player_field.deck player_field.deck
when :graveyard when :graveyard
player_field.graveyard player_field.graveyard
when :extra when :extra
player_field.extra player_field.extra
when :removed when :removed
player_field.removed player_field.removed
end end
end end
def run def run
$log.info('移动操作执行'){self.inspect} $log.info('移动操作执行'){self.inspect}
from_field = parse_field(@from_pos) from_field = parse_field(@from_pos)
from_pos = case @from_pos from_pos = case @from_pos
when 0..10 when 0..10
@from_pos @from_pos
when 11..70 when 11..70
@from_pos - 11 @from_pos - 11
when 71..130 when 71..130
@from_pos - 71 @from_pos - 71
when :handtop when :handtop
player_field.hand.size - 1 player_field.hand.size - 1
when :decktop when :decktop
player_field.deck.size - 1 player_field.deck.size - 1
when nil when nil
nil nil
else else
(@card.is_a?(Game_Card) ? from_field.index(@card) : from_field.index{|card|card.card == @card}) || from_field.index{|card|!card.known?} (@card.is_a?(Game_Card) ? from_field.index(@card) : from_field.index{|card|card.card == @card}) || from_field.index{|card|!card.known?}
end end
to_field = parse_field(@to_pos) to_field = parse_field(@to_pos)
card = if from_pos card = if from_pos
case @card case @card
when Game_Card when Game_Card
@card @card
when Card when Card
if from_field[from_pos] if from_field[from_pos]
from_field[from_pos].card = @card from_field[from_pos].card = @card
else else
$log.warn('移动操作1'){'似乎凭空产生了卡片' + self.inspect} $log.warn('移动操作1'){'似乎凭空产生了卡片' + self.inspect}
from_field[from_pos] = Game_Card.new(@card) from_field[from_pos] = Game_Card.new(@card)
end end
from_field[from_pos] from_field[from_pos]
else else
from_field[from_pos] || Game_Card.new from_field[from_pos] || Game_Card.new
end end
else #没有来源 else #没有来源
$log.warn('移动操作2'){'似乎凭空产生了卡片' + self.inspect} $log.warn('移动操作2'){'似乎凭空产生了卡片' + self.inspect}
Game_Card.new(@card) Game_Card.new(@card)
end end
if @position if @position
if @position == :"face-up" if @position == :"face-up"
if card.position != :attack and (6..10).include?(@to_pos || @from_pos) #里侧表示的怪兽 if card.position != :attack and (6..10).include?(@to_pos || @from_pos) #里侧表示的怪兽
card.position = :defense card.position = :defense
else else
card.position = :attack card.position = :attack
end end
else else
card.position = @position card.position = @position
end end
end end
if @to_pos if @to_pos
if from_pos if from_pos
if from_field == player_field.field if from_field == player_field.field
from_field[from_pos] = nil from_field[from_pos] = nil
else else
from_field.delete_at from_pos from_field.delete_at from_pos
end end
end end
case @to_pos case @to_pos
when 0..10 when 0..10
to_field[@to_pos] = card to_field[@to_pos] = card
when :hand, :deck, :decktop, :extra, :graveyard, :removed when :hand, :deck, :decktop, :extra, :graveyard, :removed
to_field.push card to_field.push card
when :deckbottom when :deckbottom
to_field.unshift card to_field.unshift card
else else
$log.error('移动操作3'){'错误的to_pos' + self.inspect} $log.error('移动操作3'){'错误的to_pos' + self.inspect}
end end
end end
if from_field == player_field.hand and !@card || !@card.known? if from_field == player_field.hand and !@card || !@card.known?
case @to_pos case @to_pos
when 0..5 when 0..5
player_field.hand.each{|card|card.card = Card::Unknown if card.known? and !card.monster?} player_field.hand.each{|card|card.card = Card::Unknown if card.known? and !card.monster?}
when 6..10 when 6..10
player_field.hand.each{|card|card.card = Card::Unknown if card.known? and card.monster?} player_field.hand.each{|card|card.card = Card::Unknown if card.known? and card.monster?}
else else
player_field.hand.each{|card|card.card = Card::Unknown if card.known?} player_field.hand.each{|card|card.card = Card::Unknown if card.known?}
end end
end end
super super
end end
end end
class Set < Move class Set < Move
def initialize(from_player, from_pos, to_pos, card) def initialize(from_player, from_pos, to_pos, card)
super(from_player, from_pos, to_pos, card, nil, :set) super(from_player, from_pos, to_pos, card, nil, :set)
end end
end end
class Activate < Move class Activate < Move
def initialize(from_player, from_pos, to_pos, card) def initialize(from_player, from_pos, to_pos, card)
super(from_player, from_pos, to_pos, card, nil, :attack) super(from_player, from_pos, to_pos, card, nil, :attack)
end end
end end
class Summon < Move class Summon < Move
def initialize(from_player, from_pos, to_pos, card, msg=nil) def initialize(from_player, from_pos, to_pos, card, msg=nil)
super(from_player, from_pos, to_pos, card, msg, :attack) super(from_player, from_pos, to_pos, card, msg, :attack)
end end
end end
class SpecialSummon < Move class SpecialSummon < Move
def initialize(from_player, from_pos, to_pos, card, msg=nil, position=:attack) def initialize(from_player, from_pos, to_pos, card, msg=nil, position=:attack)
super(from_player, from_pos, to_pos, card, msg, position) super(from_player, from_pos, to_pos, card, msg, position)
end end
end end
class SendToGraveyard < Move class SendToGraveyard < Move
def initialize(from_player, from_pos, card) def initialize(from_player, from_pos, card)
super(from_player, from_pos, :graveyard, card, nil, :attack) super(from_player, from_pos, :graveyard, card, nil, :attack)
end end
end end
class Remove < Move class Remove < Move
def initialize(from_player, from_pos, card) def initialize(from_player, from_pos, card)
super(from_player, from_pos, :removed, card, nil, :attack) super(from_player, from_pos, :removed, card, nil, :attack)
end end
end end
class ReturnToHand < Move class ReturnToHand < Move
def initialize(from_player, from_pos, card) def initialize(from_player, from_pos, card)
super(from_player, from_pos, :hand, card, nil, :set) super(from_player, from_pos, :hand, card, nil, :set)
end end
end end
class ReturnToDeck < Move class ReturnToDeck < Move
def initialize(from_player, from_pos, card) def initialize(from_player, from_pos, card)
super(from_player, from_pos, :deck, card, nil, :set) super(from_player, from_pos, :deck, card, nil, :set)
end end
end end
class ReturnToDeckBottom < Move class ReturnToDeckBottom < Move
def initialize(from_player, from_pos, card) def initialize(from_player, from_pos, card)
super(from_player, from_pos, :deckbottom, card, nil, :set) super(from_player, from_pos, :deckbottom, card, nil, :set)
end end
end end
class ReturnToExtra < Move class ReturnToExtra < Move
def initialize(from_player, from_pos, card) def initialize(from_player, from_pos, card)
super(from_player, from_pos, :extra, card, nil, :set) super(from_player, from_pos, :extra, card, nil, :set)
end end
end end
class Control < Move class Control < Move
def initialize(from_player, from_pos, card) def initialize(from_player, from_pos, card)
super(from_player, from_pos, nil, card) super(from_player, from_pos, nil, card)
end end
def run def run
to_pos = opponent_field.field[6..10].index(nil)+6 to_pos = opponent_field.field[6..10].index(nil)+6
unless to_pos unless to_pos
$log.warn('转移控制权'){'没有空余场位'} $log.warn('转移控制权'){'没有空余场位'}
return return
end end
card = if @card.is_a? Game_Card card = if @card.is_a? Game_Card
@card @card
elsif player_field.field[from_pos] elsif player_field.field[from_pos]
card = player_field.field[from_pos] card = player_field.field[from_pos]
card.card = @card card.card = @card
card card
else else
$log.warn('转移控制权'){'似乎凭空产生了卡片'+self.inspect} $log.warn('转移控制权'){'似乎凭空产生了卡片'+self.inspect}
Game_Card.new(@card) Game_Card.new(@card)
end end
player_field.field[from_pos] = nil player_field.field[from_pos] = nil
opponent_field.field[to_pos] = card opponent_field.field[to_pos] = card
end end
end end
class SendToOpponentGraveyard < SendToGraveyard class SendToOpponentGraveyard < SendToGraveyard
def run def run
card = if @card.is_a? Game_Card card = if @card.is_a? Game_Card
@card @card
elsif player_field.field[from_pos] elsif player_field.field[from_pos]
card = player_field.field[from_pos] card = player_field.field[from_pos]
card.card = @card card.card = @card
card card
else else
Game_Card.new(@card) Game_Card.new(@card)
end end
player_field.field[from_pos] = nil player_field.field[from_pos] = nil
opponent_field.graveyard.unshift card opponent_field.graveyard.unshift card
end end
end end
class Tribute < SendToGraveyard; end class Tribute < SendToGraveyard; end
class Discard < SendToGraveyard; end class Discard < SendToGraveyard; end
class ChangePosition < Move class ChangePosition < Move
def initialize(from_player, from_pos, card, position) def initialize(from_player, from_pos, card, position)
super(from_player, from_pos, from_pos, card, nil, position) super(from_player, from_pos, from_pos, card, nil, position)
end end
end end
class Flip < ChangePosition class Flip < ChangePosition
def initialize(from_player, from_pos, card, position=:defense) def initialize(from_player, from_pos, card, position=:defense)
super(from_player, from_pos, card, position) super(from_player, from_pos, card, position)
end end
end end
class FlipSummon < Flip class FlipSummon < Flip
def initialize(from_player, from_pos, card) def initialize(from_player, from_pos, card)
super(from_player, from_pos, card, :attack) super(from_player, from_pos, card, :attack)
end end
end end
class Draw < Move class Draw < Move
def initialize(from_player=true, msg=nil) def initialize(from_player=true, msg=nil)
@from_player = from_player @from_player = from_player
super(from_player, :decktop, :hand, nil, msg, :set) super(from_player, :decktop, :hand, nil, msg, :set)
end end
end end
class Counter < Action class Counter < Action
end end
class MultiDraw < Action class MultiDraw < Action
def initialize(from_player, count, msg=nil) def initialize(from_player, count, msg=nil)
super(from_player, msg) super(from_player, msg)
@count = count @count = count
end end
def run def run
super super
player_field.hand.concat player_field.deck.pop(@count) player_field.hand.concat player_field.deck.pop(@count)
end end
end end
class MultiMove < Action class MultiMove < Action
def initialize(from_player, from_pos, to_pos, cards=nil) def initialize(from_player, from_pos, to_pos, cards=nil)
super(from_player) super(from_player)
@from_pos = from_pos @from_pos = from_pos
@to_pos = to_pos @to_pos = to_pos
@cards = cards @cards = cards
end end
def run def run
from_field = case @from_pos from_field = case @from_pos
when :hand when :hand
player_field.hand player_field.hand
when :graveyard when :graveyard
player_field.graveyard player_field.graveyard
when :spellsandtraps when :spellsandtraps
player_field.field[0..5] player_field.field[0..5]
when :monsters when :monsters
player_field.field[6..10] player_field.field[6..10]
end end
@cards = if @cards @cards = if @cards
@cards.collect do |card| @cards.collect do |card|
index = from_field.index{|fieldcard|fieldcard and fieldcard.card == card} || from_field.index{|fieldcard|fieldcard and !fieldcard.known?} index = from_field.index{|fieldcard|fieldcard and fieldcard.card == card} || from_field.index{|fieldcard|fieldcard and !fieldcard.known?}
if index if index
fieldcard = from_field[index] fieldcard = from_field[index]
from_field[index] = nil from_field[index] = nil
fieldcard.card = card fieldcard.card = card
fieldcard fieldcard
else else
$log.warn '似乎凭空产生了卡片' $log.warn '似乎凭空产生了卡片'
Game_Card.new(@card) Game_Card.new(@card)
end end
end end
else else
from_field.compact from_field.compact
end end
to_field, position = case @to_pos to_field, position = case @to_pos
when :hand when :hand
[player_field.hand, :set] [player_field.hand, :set]
when :graveyard when :graveyard
[player_field.graveyard, :attack] [player_field.graveyard, :attack]
when :deck when :deck
[player_field.deck, :set] [player_field.deck, :set]
when :removed when :removed
[player_field.removed, :attack] [player_field.removed, :attack]
end end
#执行部分 #执行部分
case @from_pos case @from_pos
when :hand when :hand
player_field.hand.clear player_field.hand.clear
when :graveyard when :graveyard
player_field.graveyard.clear player_field.graveyard.clear
when :spellsandtraps when :spellsandtraps
player_field.field[0..5] = Array.new(6, nil) player_field.field[0..5] = Array.new(6, nil)
when :monsters when :monsters
player_field.field[6..10] = Array.new(5, nil) player_field.field[6..10] = Array.new(5, nil)
end end
if to_field == player_field.hand or to_field == player_field.deck if to_field == player_field.hand or to_field == player_field.deck
@cards.each{|card|card.position = position; to_field.push card} @cards.each{|card|card.position = position; to_field.push card}
else else
@cards.each{|card|card.position = position; to_field.unshift card} @cards.each{|card|card.position = position; to_field.unshift card}
end end
super super
end end
end end
=begin #似乎不需要细分 =begin #似乎不需要细分
class MonstersSendToGraveyard < MultiMove class MonstersSendToGraveyard < MultiMove
def initialize(from_player, cards) def initialize(from_player, cards)
super(from_player, :monsters, :graveyard, cards) super(from_player, :monsters, :graveyard, cards)
end end
end end
class MonstersRemove < MultiMove class MonstersRemove < MultiMove
def initialize(from_player, cards) def initialize(from_player, cards)
super(from_player, :monsters, :remove, cards) super(from_player, :monsters, :remove, cards)
end end
end end
class MonstersReturnToDeck < MultiMove class MonstersReturnToDeck < MultiMove
def initialize(from_player, cards) def initialize(from_player, cards)
super(from_player, :monsters, :deck, cards) super(from_player, :monsters, :deck, cards)
end end
end end
class MonstersReturnToHand < MultiMove class MonstersReturnToHand < MultiMove
def initialize(from_player, cards) def initialize(from_player, cards)
super(from_player, :monsters, :hand, cards) super(from_player, :monsters, :hand, cards)
end end
end end
class SpellsAndTrapsSendToGraveyard < MultiMove class SpellsAndTrapsSendToGraveyard < MultiMove
def initialize(from_player, cards) def initialize(from_player, cards)
super(from_player, :spellsandtraps, :graveyard, cards) super(from_player, :spellsandtraps, :graveyard, cards)
end end
end end
class SpellsAndTrapsRemove < MultiMove class SpellsAndTrapsRemove < MultiMove
def initialize(from_player, cards) def initialize(from_player, cards)
super(from_player, :spellsandtraps, :remove, cards) super(from_player, :spellsandtraps, :remove, cards)
end end
end end
class SpellsAndTrapsReturnToDeck < MultiMove class SpellsAndTrapsReturnToDeck < MultiMove
def initialize(from_player, cards) def initialize(from_player, cards)
super(from_player, :spellsandtraps, :deck, cards) super(from_player, :spellsandtraps, :deck, cards)
end end
end end
class SpellsAndTrapsReturnToHand < MultiMove class SpellsAndTrapsReturnToHand < MultiMove
def initialize(from_player, cards) def initialize(from_player, cards)
super(from_player, :spellsandtraps, :hand, cards) super(from_player, :spellsandtraps, :hand, cards)
end end
end end
class HandSendToGraveyard < MultiMove class HandSendToGraveyard < MultiMove
def initialize(from_player, cards) def initialize(from_player, cards)
super(from_player, :hand, :graveyard, cards) super(from_player, :hand, :graveyard, cards)
end end
end end
class HandRemove < MultiMove class HandRemove < MultiMove
def initialize(from_player, cards) def initialize(from_player, cards)
super(from_player, :hand, :remove, cards) super(from_player, :hand, :remove, cards)
end end
end end
class HandReturnToDeck < MultiMove class HandReturnToDeck < MultiMove
def initialize(from_player, cards) def initialize(from_player, cards)
super(from_player, :hand, :deck, cards) super(from_player, :hand, :deck, cards)
end end
end end
=end =end
class RefreshField < Action class RefreshField < Action
attr_reader :field attr_reader :field
def initialize(from_player, field, msg=nil) def initialize(from_player, field, msg=nil)
super(from_player, msg) super(from_player, msg)
@field = field @field = field
end end
def run def run
super super
return if @field.is_a? Game_Field #本地信息,无需处理。 return if @field.is_a? Game_Field #本地信息,无需处理。
player_field.lp = @field[:lp] player_field.lp = @field[:lp]
if player_field.hand.size > @field[:hand] if player_field.hand.size > @field[:hand]
player_field.hand.pop(player_field.hand.size-@field[:hand]) player_field.hand.pop(player_field.hand.size-@field[:hand])
elsif player_field.hand.size < @field[:hand] elsif player_field.hand.size < @field[:hand]
(@field[:hand]-player_field.hand.size).times{$log.warn('刷新场地-手卡'){'似乎凭空产生了卡片'};player_field.hand.push Game_Card.new(Card::Unknown)} (@field[:hand]-player_field.hand.size).times{$log.warn('刷新场地-手卡'){'似乎凭空产生了卡片'};player_field.hand.push Game_Card.new(Card::Unknown)}
end end
if player_field.deck.size > @field[:deck] if player_field.deck.size > @field[:deck]
player_field.deck.pop(player_field.deck.size-@field[:deck]) player_field.deck.pop(player_field.deck.size-@field[:deck])
elsif player_field.deck.size < @field[:deck] elsif player_field.deck.size < @field[:deck]
(@field[:deck]-player_field.deck.size).times{$log.warn('刷新场地-卡组'){'似乎凭空产生了卡片'};player_field.deck.push Game_Card.new(Card::Unknown)} (@field[:deck]-player_field.deck.size).times{$log.warn('刷新场地-卡组'){'似乎凭空产生了卡片'};player_field.deck.push Game_Card.new(Card::Unknown)}
end end
if player_field.graveyard.size > @field[:graveyard] if player_field.graveyard.size > @field[:graveyard]
player_field.graveyard.pop(player_field.graveyard.size-@field[:graveyard]) player_field.graveyard.pop(player_field.graveyard.size-@field[:graveyard])
elsif player_field.graveyard.size < @field[:graveyard] elsif player_field.graveyard.size < @field[:graveyard]
(@field[:graveyard]-player_field.graveyard.size).times{$log.warn('刷新场地-墓地'){'似乎凭空产生了卡片'};player_field.graveyard.push Game_Card.new(Card::Unknown)} (@field[:graveyard]-player_field.graveyard.size).times{$log.warn('刷新场地-墓地'){'似乎凭空产生了卡片'};player_field.graveyard.push Game_Card.new(Card::Unknown)}
end end
(0..10).each do |pos| (0..10).each do |pos|
if @field[pos] if @field[pos]
if player_field.field[pos] if player_field.field[pos]
player_field.field[pos].card = @field[pos][:card] player_field.field[pos].card = @field[pos][:card]
else else
$log.warn("刷新场地-#{pos}"){'似乎凭空产生了卡片'} $log.warn("刷新场地-#{pos}"){'似乎凭空产生了卡片'}
player_field.field[pos] = Game_Card.new(@field[pos][:card]) player_field.field[pos] = Game_Card.new(@field[pos][:card])
end end
player_field.field[pos].position = @field[pos][:position] player_field.field[pos].position = @field[pos][:position]
else else
player_field.field[pos] = nil player_field.field[pos] = nil
end end
end end
end end
end end
class TurnEnd < RefreshField class TurnEnd < RefreshField
attr_reader :turn attr_reader :turn
def initialize(from_player, field, turn, msg=nil) def initialize(from_player, field, turn, msg=nil)
super(from_player, field, msg) super(from_player, field, msg)
@turn = turn @turn = turn
end end
def run def run
$game.phase = :DP $game.phase = :DP
$game.turn = @turn.next $game.turn = @turn.next
$game.turn_player = !from_player $game.turn_player = !from_player
super super
end end
end end
class Show < Move class Show < Move
attr_reader :from_pos, :card attr_reader :from_pos, :card
def initialize(from_player, from_pos, card) def initialize(from_player, from_pos, card)
super(from_player, from_pos, nil, card) super(from_player, from_pos, nil, card)
@from_pos = from_pos @from_pos = from_pos
@card = card @card = card
end end
end end
class MultiShow < Action class MultiShow < Action
def initialize(from_player, from_pos=nil, cards) def initialize(from_player, from_pos=nil, cards)
super(from_player, nil) super(from_player, nil)
@from_pos = from_pos @from_pos = from_pos
@cards = cards @cards = cards
end end
def run def run
return if @cards[0].is_a? Game_Card #本地消息,不处理 return if @cards[0].is_a? Game_Card #本地消息,不处理
case @from_pos case @from_pos
when :hand when :hand
if player_field.hand.size > @cards.size if player_field.hand.size > @cards.size
player_field.hand.pop(player_field.hand.size-@cards.size) player_field.hand.pop(player_field.hand.size-@cards.size)
end end
@cards.each_with_index do |card, index| @cards.each_with_index do |card, index|
if player_field.hand[index] if player_field.hand[index]
player_field.hand[index].card = card player_field.hand[index].card = card
else else
player_field.hand[index] = Game_Card.new card player_field.hand[index] = Game_Card.new card
end end
end end
when 71..130 when 71..130
cards = @cards.to_enum cards = @cards.to_enum
player_field.deck[@from_pos-71, @cards.size].each do |game_card| player_field.deck[@from_pos-71, @cards.size].each do |game_card|
game_card.card = cards.next game_card.card = cards.next
end end
end end
end end
end end
class EffectActivate < Move class EffectActivate < Move
def initialize(from_player, from_pos, card) def initialize(from_player, from_pos, card)
if (0..10).include?(from_pos) if (0..10).include?(from_pos)
position = :"face-up" position = :"face-up"
else else
position = nil position = nil
end end
super(from_player, from_pos, to_pos, card, nil, position) super(from_player, from_pos, to_pos, card, nil, position)
end end
end end
class ActivateAsk < Action class ActivateAsk < Action
def initialize(from_player) def initialize(from_player)
super(from_player) super(from_player)
end end
end end
class ActivateAnswer < Action class ActivateAnswer < Action
def initialize(from_player, activate) def initialize(from_player, activate)
super(from_player) super(from_player)
@activate = activate @activate = activate
end end
end end
class Target < Action class Target < Action
def initialize(from_player, from_pos, card, target_player ,target_pos, target_card) def initialize(from_player, from_pos, card, target_player ,target_pos, target_card)
super(from_player) super(from_player)
@from_pos = from_pos @from_pos = from_pos
@card = card @card = card
@target_pos = target_player @target_pos = target_player
@target_pos = target_pos @target_pos = target_pos
@target_card = target_card @target_card = target_card
end end
def run def run
card = if @card.is_a? Game_Card card = if @card.is_a? Game_Card
@card @card
else else
if player_field.field[@from_pos] if player_field.field[@from_pos]
player_field.field[@from_pos].card = @card player_field.field[@from_pos].card = @card
player_field.field[@from_pos] player_field.field[@from_pos]
else else
$log.warn('攻击宣言'){'似乎凭空产生了卡片' + self.inspect} $log.warn('攻击宣言'){'似乎凭空产生了卡片' + self.inspect}
player_field[@from_pos] = Game_Card.new(@card) player_field[@from_pos] = Game_Card.new(@card)
end end
end end
$log.info('攻击宣言'){self.inspect} $log.info('攻击宣言'){self.inspect}
end end
end end
class ViewDeck < Action; end class ViewDeck < Action; end
class LP < Action class LP < Action
attr_accessor :operator, :value attr_accessor :operator, :value
def initialize(from_player, operator, value) def initialize(from_player, operator, value)
super(from_player) super(from_player)
@operator = operator @operator = operator
@value = value @value = value
end end
def run def run
case operator case operator
when :lose when :lose
player_field.lp -= @value player_field.lp -= @value
when :increase when :increase
player_field.lp += @value player_field.lp += @value
when :become when :become
player_field.lp = @value player_field.lp = @value
end end
end end
end end
class Attack < Action class Attack < Action
def initialize(from_player, from_pos, to_pos=nil, card) def initialize(from_player, from_pos, to_pos=nil, card)
super(from_player) super(from_player)
@from_pos = from_pos @from_pos = from_pos
@to_pos = to_pos @to_pos = to_pos
@card = card @card = card
end end
def run def run
card = if @card.is_a? Game_Card card = if @card.is_a? Game_Card
@card @card
elsif @from_pos elsif @from_pos
if player_field.field[@from_pos] if player_field.field[@from_pos]
player_field.field[@from_pos].card = @card player_field.field[@from_pos].card = @card
else else
$log.warn('攻击宣言'){'似乎凭空产生了卡片' + self.inspect} $log.warn('攻击宣言'){'似乎凭空产生了卡片' + self.inspect}
player_field.field[@from_pos] = Game_Card.new(@card) player_field.field[@from_pos] = Game_Card.new(@card)
player_field.field[@from_pos].position = :attack player_field.field[@from_pos].position = :attack
end end
player_field.field[@from_pos] player_field.field[@from_pos]
else else
$log.info('直接攻击'){'功能未实现'} $log.info('直接攻击'){'功能未实现'}
@card @card
end end
end end
end end
class Counter < Action class Counter < Action
def initialize(from_player, from_pos, card, operator, value) def initialize(from_player, from_pos, card, operator, value)
super(from_player) super(from_player)
@from_pos = from_pos @from_pos = from_pos
@card = card @card = card
@operator = operator @operator = operator
@value = value @value = value
end end
def run def run
card = if @card.is_a? Game_Card card = if @card.is_a? Game_Card
@card @card
else else
if player_field.field[@from_pos] if player_field.field[@from_pos]
player_field.field[@from_pos].card = @card player_field.field[@from_pos].card = @card
else else
$log.warn('指示物操作'){'似乎凭空产生了卡片' + self.inspect} $log.warn('指示物操作'){'似乎凭空产生了卡片' + self.inspect}
player_field.field[@from_pos] = Game_Card.new(@card) player_field.field[@from_pos] = Game_Card.new(@card)
player_field.field[@from_pos].position = :attack player_field.field[@from_pos].position = :attack
end end
player_field.field[@from_pos] player_field.field[@from_pos]
end end
case @operator case @operator
when :become when :become
card.counters = @value card.counters = @value
else else
$log.warn('指示物操作'){'become以外的未实现' + self.inspect} $log.warn('指示物操作'){'become以外的未实现' + self.inspect}
end end
end end
end end
class Note < Action class Note < Action
def initialize(from_player, from_pos, card, note) def initialize(from_player, from_pos, card, note)
super(from_player) super(from_player)
@from_pos = from_pos @from_pos = from_pos
@card = card @card = card
@note = note @note = note
end end
def run def run
card = if @card.is_a? Game_Card card = if @card.is_a? Game_Card
@card @card
else else
if player_field.field[@from_pos] if player_field.field[@from_pos]
player_field.field[@from_pos].card = @card player_field.field[@from_pos].card = @card
else else
$log.warn('指示物操作'){'似乎凭空产生了卡片' + self.inspect} $log.warn('指示物操作'){'似乎凭空产生了卡片' + self.inspect}
player_field.field[@from_pos] = Game_Card.new(@card) player_field.field[@from_pos] = Game_Card.new(@card)
player_field.field[@from_pos].position = :attack player_field.field[@from_pos].position = :attack
end end
player_field.field[@from_pos] player_field.field[@from_pos]
end end
card.note = @note card.note = @note
end end
end end
class Token < SpecialSummon class Token < SpecialSummon
def initialize(from_player, to_pos, card, position=:defense) def initialize(from_player, to_pos, card, position=:defense)
super(from_player, nil, to_pos, card) super(from_player, nil, to_pos, card)
end end
end end
class MultiToken < SpecialSummon class MultiToken < SpecialSummon
def initialize(from_player, num, card, position=:attack) def initialize(from_player, num, card, position=:attack)
super(from_player, nil, nil, card) super(from_player, nil, nil, card)
@num = num @num = num
end end
def run def run
@num.times do @num.times do
@to_pos = player_field.field[6..10].index(nil)+6 @to_pos = player_field.field[6..10].index(nil)+6
super super
end end
end end
end end
class Add < Action class Add < Action
def initialize(from_player, card) def initialize(from_player, card)
super(from_player) super(from_player)
@card = card @card = card
end end
def run def run
if @card.extra? if @card.extra?
player_field.extra << Game_Card.new(@card) player_field.extra << Game_Card.new(@card)
else else
player_field.hand << Game_Card.new(@card) player_field.hand << Game_Card.new(@card)
end end
end end
end end
class Destroy < Action class Destroy < Action
def initialize(from_player, from_pos, card) def initialize(from_player, from_pos, card)
super(from_player) super(from_player)
@from_pos = from_pos @from_pos = from_pos
@card = card @card = card
end end
def run def run
if @from_pos <= 10 if @from_pos <= 10
player_field.field[@from_pos] = nil player_field.field[@from_pos] = nil
else else
player_field.hand.delete_at(@from_pos - 11) player_field.hand.delete_at(@from_pos - 11)
end end
end end
end end
class CardInfo < Action class CardInfo < Action
def initialize(card, card_type, atk, _def, attribute, type, level, lore) def initialize(card, card_type, atk, _def, attribute, type, level, lore)
return unless card.diy? return unless card.diy?
card.card_type = card_type card.card_type = card_type
#card.monster_type = monster_type #card.monster_type = monster_type
card.atk = atk card.atk = atk
card.def = _def card.def = _def
card.attribute = attribute card.attribute = attribute
card.type = type card.type = type
card.level = level card.level = level
card.lore = lore card.lore = lore
end end
end end
class Unknown < Action class Unknown < Action
def initialize(str) def initialize(str)
@str = str @str = str
$log.warn('unkonwn action') { str } $log.warn('unkonwn action') { str }
end end
def run def run
$log.warn('unkonwn action run'){ @str } $log.warn('unkonwn action run'){ @str }
end end
end end
def self.reset def self.reset
@@id=1 @@id=1
end end
reset reset
end end
\ No newline at end of file
#encoding: UTF-8 #encoding: UTF-8
#==Card Model #==Card Model
class Card class Card
require 'sqlite3' require 'sqlite3'
@db = SQLite3::Database.new( "data/data.sqlite" ) @db = SQLite3::Database.new( "data/data.sqlite" )
@all = {} @all = {}
@diy = {} @diy = {}
@count = @db.get_first_value("select COUNT(*) from `yu-gi-oh`") rescue 0 @count = @db.get_first_value("select COUNT(*) from `yu-gi-oh`") rescue 0
@db.results_as_hash = true @db.results_as_hash = true
PicPath = if RUBY_PLATFORM["win"] || RUBY_PLATFORM["ming"] PicPath = if RUBY_PLATFORM["win"] || RUBY_PLATFORM["ming"]
require 'win32/registry' require 'win32/registry'
ospicpath = Win32::Registry::HKEY_CURRENT_USER.open('Software\OCGSOFT\Cards'){|reg|reg['Path']} rescue '' ospicpath = Win32::Registry::HKEY_CURRENT_USER.open('Software\OCGSOFT\Cards'){|reg|reg['Path']} rescue ''
ospicpath.force_encoding "GBK" ospicpath.force_encoding "GBK"
ospicpath.encode "UTF-8" ospicpath.encode "UTF-8"
else else
'' #其他操作系统卡图存放位置标准尚未制定。 '' #其他操作系统卡图存放位置标准尚未制定。
end end
CardBack = Surface.load("graphics/field/card.jpg").display_format rescue nil CardBack = Surface.load("graphics/field/card.jpg").display_format rescue nil
CardBack_Small = Surface.load("graphics/field/card_small.gif").display_format rescue nil CardBack_Small = Surface.load("graphics/field/card_small.gif").display_format rescue nil
class << self class << self
def find(id, order_by=nil) def find(id, order_by=nil)
case id case id
when Integer when Integer
@all[id] || old_new(@db.get_first_row("select * from `yu-gi-oh` where id = #{id}")) @all[id] || old_new(@db.get_first_row("select * from `yu-gi-oh` where id = #{id}"))
when Symbol when Symbol
row = @db.get_first_row("select * from `yu-gi-oh` where name = '#{id}'") row = @db.get_first_row("select * from `yu-gi-oh` where name = '#{id}'")
if row if row
@all[row['id'].to_i] || old_new(row) @all[row['id'].to_i] || old_new(row)
else else
@diy[id] ||= Card.new('id' => 0, 'number' => :"00000000", 'name' => id, 'attribute' => :, 'level' => 1, 'card_type' => :通常怪兽, 'stats' => "", 'archettypes' => "", 'mediums' => "", 'lore' => "") @diy[id] ||= Card.new('id' => 0, 'number' => :"00000000", 'name' => id, 'attribute' => :, 'level' => 1, 'card_type' => :通常怪兽, 'stats' => "", 'archettypes' => "", 'mediums' => "", 'lore' => "")
end end
when Hash when Hash
old_new(id) old_new(id)
when nil when nil
Card::Unknown Card::Unknown
else else
sql = "select * from `yu-gi-oh` where " << id sql = "select * from `yu-gi-oh` where " << id
sql << " order by #{order_by}" if order_by sql << " order by #{order_by}" if order_by
$log.debug('查询卡片执行SQL'){sql} $log.debug('查询卡片执行SQL'){sql}
@db.execute(sql).collect {|row|@all[row['id'].to_i] || old_new(row)} @db.execute(sql).collect {|row|@all[row['id'].to_i] || old_new(row)}
end end
end end
def all def all
if @all.size != @count if @all.size != @count
sql = "select * from `yu-gi-oh` where id not in (#{@all.keys.join(', ')})" sql = "select * from `yu-gi-oh` where id not in (#{@all.keys.join(', ')})"
@db.execute(sql).each{|row|old_new(row)} @db.execute(sql).each{|row|old_new(row)}
end end
@all @all
end end
def cache def cache
@all @all
end end
alias old_new new alias old_new new
def new(id) def new(id)
find(id) find(id)
end end
def load_from_ycff3(db = RUBY_PLATFORM["win"] || RUBY_PLATFORM["ming"] ? (require 'win32/registry';Win32::Registry::HKEY_CURRENT_USER.open('Software\OCGSOFT\YFCC'){|reg|reg['Path']+"YGODATA/YGODAT.dat"} rescue '') : '') def load_from_ycff3(db = RUBY_PLATFORM["win"] || RUBY_PLATFORM["ming"] ? (require 'win32/registry';Win32::Registry::HKEY_CURRENT_USER.open('Software\OCGSOFT\YFCC'){|reg|reg['Path']+"YGODATA/YGODAT.dat"} rescue '') : '')
require 'win32ole' require 'win32ole'
conn = WIN32OLE.new('ADODB.Connection') conn = WIN32OLE.new('ADODB.Connection')
conn.open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + db + ";Jet OLEDB:Database Password=paradisefox@sohu.com" ) conn.open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + db + ";Jet OLEDB:Database Password=paradisefox@sohu.com" )
records = WIN32OLE.new('ADODB.Recordset') records = WIN32OLE.new('ADODB.Recordset')
records.open("select EFFECT from YGOEFFECT", conn) records.open("select EFFECT from YGOEFFECT", conn)
stats = records.GetRows.first stats = records.GetRows.first
stats.unshift nil stats.unshift nil
records.close records.close
records = WIN32OLE.new('ADODB.Recordset') records = WIN32OLE.new('ADODB.Recordset')
records.open("YGODATA", conn) records.open("YGODATA", conn)
records.MoveNext #跳过首行那个空白卡 records.MoveNext #跳过首行那个空白卡
sql = "" sql = ""
while !records.EOF while !records.EOF
sql << "INSERT INTO `yu-gi-oh` VALUES( sql << "INSERT INTO `yu-gi-oh` VALUES(
#{records.Fields.Item("CardID").value-1}, #{records.Fields.Item("CardID").value-1},
'#{records.Fields.Item("CardPass").value}', '#{records.Fields.Item("CardPass").value}',
'#{records.Fields.Item("SCCardName").value}', '#{records.Fields.Item("SCCardName").value}',
'#{records.Fields.Item("SCCardType").value == "XYZ怪兽" ? "超量怪兽" : records.Fields.Item("SCCardType").value}', '#{records.Fields.Item("SCCardType").value == "XYZ怪兽" ? "超量怪兽" : records.Fields.Item("SCCardType").value}',
#{records.Fields.Item("SCDCardType").value == '    ' ? "NULL" : "'#{records.Fields.Item("SCDCardType").value}'"}, #{records.Fields.Item("SCDCardType").value == '    ' ? "NULL" : "'#{records.Fields.Item("SCDCardType").value}'"},
#{records.Fields.Item("CardATK").value || "NULL"}, #{records.Fields.Item("CardATK").value || "NULL"},
#{records.Fields.Item("CardDef").value || "NULL"}, #{records.Fields.Item("CardDef").value || "NULL"},
#{records.Fields.Item("SCCardAttribute").value == '    ' ? "NULL" : "'#{records.Fields.Item("SCCardAttribute").value}'"}, #{records.Fields.Item("SCCardAttribute").value == '    ' ? "NULL" : "'#{records.Fields.Item("SCCardAttribute").value}'"},
#{records.Fields.Item("SCCardRace").value == '    ' ? "NULL" : "'#{records.Fields.Item("SCCardRace").value}'"}, #{records.Fields.Item("SCCardRace").value == '    ' ? "NULL" : "'#{records.Fields.Item("SCCardRace").value}'"},
#{records.Fields.Item("CardStarNum").value || "NULL"}, #{records.Fields.Item("CardStarNum").value || "NULL"},
'#{records.Fields.Item("SCCardDepict").value}', '#{records.Fields.Item("SCCardDepict").value}',
#{case records.Fields.Item("ENCardBan").value; when "Normal"; 3; when "SubConfine"; 2; when "Confine"; 1; else; 0; end}, #{case records.Fields.Item("ENCardBan").value; when "Normal"; 3; when "SubConfine"; 2; when "Confine"; 1; else; 0; end},
'#{records.Fields.Item("CardEfficeType").value}', '#{records.Fields.Item("CardEfficeType").value}',
'#{records.Fields.Item("CardPhal").value.split(",").collect{|stat|stats[stat.to_i]}.join("\t")}', '#{records.Fields.Item("CardPhal").value.split(",").collect{|stat|stats[stat.to_i]}.join("\t")}',
'#{records.Fields.Item("CardCamp").value.gsub("、", "\t")}', '#{records.Fields.Item("CardCamp").value.gsub("、", "\t")}',
#{records.Fields.Item("CardISTKEN").value} #{records.Fields.Item("CardISTKEN").value}
);" );"
records.MoveNext records.MoveNext
end end
@db.execute('begin transaction') @db.execute('begin transaction')
@db.execute('DROP INDEX if exists "main"."name";') @db.execute('DROP INDEX if exists "main"."name";')
@db.execute('DROP TABLE if exists "main"."yu-gi-oh";') @db.execute('DROP TABLE if exists "main"."yu-gi-oh";')
@db.execute('CREATE TABLE "yu-gi-oh" ( @db.execute('CREATE TABLE "yu-gi-oh" (
"id" INTEGER NOT NULL, "id" INTEGER NOT NULL,
"number" TEXT NOT NULL, "number" TEXT NOT NULL,
"name" TEXT NOT NULL, "name" TEXT NOT NULL,
"card_type" TEXT NOT NULL, "card_type" TEXT NOT NULL,
"monster_type" TEXT, "monster_type" TEXT,
"atk" INTEGER, "atk" INTEGER,
"def" INTEGER, "def" INTEGER,
"attribute" TEXT, "attribute" TEXT,
"type" TEXT, "type" TEXT,
"level" INTEGER, "level" INTEGER,
"lore" TEXT NOT NULL, "lore" TEXT NOT NULL,
"status" INTEGER NOT NULL, "status" INTEGER NOT NULL,
"stats" TEXT NOT NULL, "stats" TEXT NOT NULL,
"archettypes" TEXT NOT NULL, "archettypes" TEXT NOT NULL,
"mediums" TEXT NOT NULL, "mediums" TEXT NOT NULL,
"tokens" INTEGER NOT NULL, "tokens" INTEGER NOT NULL,
PRIMARY KEY ("id") PRIMARY KEY ("id")
);') );')
@db.execute_batch(sql) @db.execute_batch(sql)
@db.execute('CREATE UNIQUE INDEX "main"."name" ON "yu-gi-oh" ("name");') @db.execute('CREATE UNIQUE INDEX "main"."name" ON "yu-gi-oh" ("name");')
@db.execute('commit transaction') @db.execute('commit transaction')
@count = @db.get_first_value("select COUNT(*) from `yu-gi-oh`") #重建计数 @count = @db.get_first_value("select COUNT(*) from `yu-gi-oh`") #重建计数
@all.clear #清空缓存 @all.clear #清空缓存
end end
end end
attr_accessor :id attr_accessor :id
attr_accessor :number attr_accessor :number
attr_accessor :name attr_accessor :name
attr_accessor :card_type attr_accessor :card_type
attr_accessor :monster_type attr_accessor :monster_type
attr_accessor :atk attr_accessor :atk
attr_accessor :def attr_accessor :def
attr_accessor :attribute attr_accessor :attribute
attr_accessor :type attr_accessor :type
attr_accessor :level attr_accessor :level
attr_accessor :lore attr_accessor :lore
attr_accessor :status attr_accessor :status
attr_accessor :stats attr_accessor :stats
attr_accessor :archettypes attr_accessor :archettypes
attr_accessor :mediums attr_accessor :mediums
attr_accessor :tokens attr_accessor :tokens
def initialize(hash) def initialize(hash)
@id = hash['id'].to_i @id = hash['id'].to_i
@number = hash['number'].to_sym @number = hash['number'].to_sym
@name = hash['name'].to_sym @name = hash['name'].to_sym
@card_type = hash['card_type'].to_sym @card_type = hash['card_type'].to_sym
@monster_type = hash["monster_type"] && hash["monster_type"].to_sym @monster_type = hash["monster_type"] && hash["monster_type"].to_sym
@atk = hash['atk'] && hash['atk'].to_i @atk = hash['atk'] && hash['atk'].to_i
@def = hash['def'] && hash['def'].to_i @def = hash['def'] && hash['def'].to_i
@attribute = hash['attribute'] && hash['attribute'].to_sym @attribute = hash['attribute'] && hash['attribute'].to_sym
@type = hash['type'] && hash['type'].to_sym @type = hash['type'] && hash['type'].to_sym
@level = hash['level'] && hash['level'].to_i @level = hash['level'] && hash['level'].to_i
@lore = hash['lore'] @lore = hash['lore']
@status = hash['status'].to_i @status = hash['status'].to_i
@stats = hash['stats'].split("\t").collect{|stat|stat.to_i} @stats = hash['stats'].split("\t").collect{|stat|stat.to_i}
@archettypes = hash['archettypes'].split("\t").collect{|archettype|stat.to_sym} @archettypes = hash['archettypes'].split("\t").collect{|archettype|stat.to_sym}
@mediums = hash['mediums'].split("\t").collect{|medium|medium.to_sym} @mediums = hash['mediums'].split("\t").collect{|medium|medium.to_sym}
@tokens = hash['tokens'].to_i @tokens = hash['tokens'].to_i
@token = hash['token'] @token = hash['token']
Card.cache[@id] = self Card.cache[@id] = self
end end
def create_image def create_image
@image ||= Surface.load("graphics/field/card.jpg").display_format @image ||= Surface.load("graphics/field/card.jpg").display_format
end end
def image def image
@image ||= Surface.load("#{PicPath}/#{@id}.jpg").display_format rescue create_image @image ||= Surface.load("#{PicPath}/#{@id}.jpg").display_format rescue create_image
end end
def image_small def image_small
@image_small ||= image.transform_surface(0xFF000000,0,54.0/image.w, 81.0/image.h,Surface::TRANSFORM_SAFE).copy_rect(1, 1, 54, 81).display_format @image_small ||= image.transform_surface(0xFF000000,0,54.0/image.w, 81.0/image.h,Surface::TRANSFORM_SAFE).copy_rect(1, 1, 54, 81).display_format
end end
def image_horizontal def image_horizontal
if @image_horizontal.nil? if @image_horizontal.nil?
image_horizontal = image_small.transform_surface(0xFF000000,90,1,1,Surface::TRANSFORM_SAFE) image_horizontal = image_small.transform_surface(0xFF000000,90,1,1,Surface::TRANSFORM_SAFE)
@image_horizontal = image_horizontal.copy_rect(1, 1, 81, 54).display_format #SDL的bug,会多出1像素的黑边 @image_horizontal = image_horizontal.copy_rect(1, 1, 81, 54).display_format #SDL的bug,会多出1像素的黑边
image_horizontal.destroy image_horizontal.destroy
end end
@image_horizontal @image_horizontal
end end
def unknown? def unknown?
@id == 1 @id == 1
end end
def monster? def monster?
[:融合怪兽, :同调怪兽, :超量怪兽, :通常怪兽, :效果怪兽, :调整怪兽, :仪式怪兽].include? card_type [:融合怪兽, :同调怪兽, :超量怪兽, :通常怪兽, :效果怪兽, :调整怪兽, :仪式怪兽].include? card_type
end end
def trap? def trap?
[:通常陷阱, :反击陷阱, :永续陷阱].include? card_type [:通常陷阱, :反击陷阱, :永续陷阱].include? card_type
end end
def spell? def spell?
[:通常魔法, :速攻魔法, :装备魔法, :场地魔法, :仪式魔法, :永续魔法].include? card_type [:通常魔法, :速攻魔法, :装备魔法, :场地魔法, :仪式魔法, :永续魔法].include? card_type
end end
def extra? def extra?
[:融合怪兽, :同调怪兽, :超量怪兽].include? card_type [:融合怪兽, :同调怪兽, :超量怪兽].include? card_type
end end
def token? def token?
@token @token
end end
def diy? def diy?
number == :"00000000" number == :"00000000"
end end
def known? def known?
self != Unknown self != Unknown
end end
def inspect def inspect
"[#{card_type}][#{name}]" "[#{card_type}][#{name}]"
end end
Unknown = Card.new('id' => 0, 'number' => :"00000000", 'attribute' => :, 'level' => 1, 'name' => "", 'lore' => '', 'card_type' => :通常怪兽, 'stats' => "", 'archettypes' => "", 'mediums' => "") Unknown = Card.new('id' => 0, 'number' => :"00000000", 'attribute' => :, 'level' => 1, 'name' => "", 'lore' => '', 'card_type' => :通常怪兽, 'stats' => "", 'archettypes' => "", 'mediums' => "")
Unknown.instance_eval{@image = CardBack; @image_small = CardBack_Small} Unknown.instance_eval{@image = CardBack; @image_small = CardBack_Small}
end end
#Card.load_from_ycff3 #Card.load_from_ycff3
\ No newline at end of file
module Dialog module Dialog
#选择文件对话框 #选择文件对话框
require 'win32api' require 'win32api'
GetOpenFileName = Win32API.new("comdlg32.dll", "GetOpenFileNameW", "p", "i") GetOpenFileName = Win32API.new("comdlg32.dll", "GetOpenFileNameW", "p", "i")
GetSaveFileName = Win32API.new("comdlg32.dll", "GetSaveFileNameW", "p", "i") GetSaveFileName = Win32API.new("comdlg32.dll", "GetSaveFileNameW", "p", "i")
OFN_EXPLORER = 0x00080000 OFN_EXPLORER = 0x00080000
OFN_PATHMUSTEXIST = 0x00000800 OFN_PATHMUSTEXIST = 0x00000800
OFN_FILEMUSTEXIST = 0x00001000 OFN_FILEMUSTEXIST = 0x00001000
OFN_ALLOWMULTISELECT = 0x00000200 OFN_ALLOWMULTISELECT = 0x00000200
OFN_FLAGS = OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_FLAGS = OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST |
OFN_ALLOWMULTISELECT OFN_ALLOWMULTISELECT
#打开网页 #打开网页
require 'win32ole' require 'win32ole'
Shell = WIN32OLE.new('Shell.Application') Shell = WIN32OLE.new('Shell.Application')
module_function module_function
def get_open_file(title="选择文件", filter = {"所有文件 (*.*)" => "*.*"}, save=nil) def get_open_file(title="选择文件", filter = {"所有文件 (*.*)" => "*.*"}, save=nil)
szFile = (0.chr * 20481).encode("UTF-16LE") szFile = (0.chr * 20481).encode("UTF-16LE")
szFileTitle = 0.chr * 2049 szFileTitle = 0.chr * 2049
szTitle = (title+"\0").encode("UTF-16LE") szTitle = (title+"\0").encode("UTF-16LE")
szFilter = (filter.flatten.join("\0")+"\0\0").encode("UTF-16LE") szFilter = (filter.flatten.join("\0")+"\0\0").encode("UTF-16LE")
szInitialDir = "\0" szInitialDir = "\0"
ofn = ofn =
[ [
76, # lStructSize L 76, # lStructSize L
0, # hwndOwner L 0, # hwndOwner L
0, # hInstance L 0, # hInstance L
szFilter, # lpstrFilter L szFilter, # lpstrFilter L
0, # lpstrCustomFilter L 0, # lpstrCustomFilter L
0, # nMaxCustFilter L 0, # nMaxCustFilter L
1, # nFilterIndex L 1, # nFilterIndex L
szFile, # lpstrFile L szFile, # lpstrFile L
szFile.size - 1, # nMaxFile L szFile.size - 1, # nMaxFile L
szFileTitle, # lpstrFileTitle L szFileTitle, # lpstrFileTitle L
szFileTitle.size - 1, # nMaxFileTitle L szFileTitle.size - 1, # nMaxFileTitle L
szInitialDir, # lpstrInitialDir L szInitialDir, # lpstrInitialDir L
szTitle, # lpstrTitle L szTitle, # lpstrTitle L
OFN_FLAGS, # Flags L OFN_FLAGS, # Flags L
0, # nFileOffset S 0, # nFileOffset S
0, # nFileExtension S 0, # nFileExtension S
0, # lpstrDefExt L 0, # lpstrDefExt L
0, # lCustData L 0, # lCustData L
0, # lpfnHook L 0, # lpfnHook L
0 # lpTemplateName L 0 # lpTemplateName L
].pack("LLLPLLLPLPLPPLS2L4") ].pack("LLLPLLLPLPLPPLS2L4")
Dir.chdir { Dir.chdir {
if save if save
GetSaveFileName.call(ofn) GetSaveFileName.call(ofn)
else else
GetOpenFileName.call(ofn) GetOpenFileName.call(ofn)
end end
} }
szFile.delete!("\0".encode("UTF-16LE")) szFile.delete!("\0".encode("UTF-16LE"))
result = szFile.encode("UTF-8") result = szFile.encode("UTF-8")
if !result.empty? and save.is_a? Array if !result.empty? and save.is_a? Array
ext = save[ofn.unpack("LLLPLLLPLPLPPLS2L4")[6] - 1] ext = save[ofn.unpack("LLLPLLLPLPLPPLS2L4")[6] - 1]
if result[-ext.size, ext.size].downcase != ext.downcase if result[-ext.size, ext.size].downcase != ext.downcase
result << ext result << ext
end end
end end
result result
end end
def web(url) def web(url)
Shell.ShellExecute url Shell.ShellExecute url
end end
def uac(command, *args) def uac(command, *args)
Shell.ShellExecute File.expand_path(command), args.join(' '), Dir.pwd, "runas" Shell.ShellExecute File.expand_path(command), args.join(' '), Dir.pwd, "runas"
end end
end end
\ No newline at end of file
#游戏适配器的抽象类 #游戏适配器的抽象类
require_relative 'game_event' require_relative 'game_event'
require_relative 'action' require_relative 'action'
require_relative 'user' require_relative 'user'
require_relative 'room' require_relative 'room'
class Game class Game
attr_reader :users, :rooms attr_reader :users, :rooms
attr_accessor :user, :room, :player_field, :opponent_field, :turn, :turn_player, :phase attr_accessor :user, :room, :player_field, :opponent_field, :turn, :turn_player, :phase
def initialize def initialize
@users = [] @users = []
@rooms = [] @rooms = []
end end
def login(username, password=nil) def login(username, password=nil)
end end
def refresh def refresh
end end
def host(room_name, room_config) def host(room_name, room_config)
end end
def join(room) def join(room)
end end
def watch(room) def watch(room)
end end
def leave def leave
end end
def action(action) def action(action)
end end
def chat(chatmessage) def chat(chatmessage)
end end
def exit def exit
$scene = Scene_Login.new if $scene $scene = Scene_Login.new if $scene
end end
def watching? def watching?
@room and @room.include? @user @room and @room.include? @user
end end
def self.deck_edit def self.deck_edit
require_relative 'window_deck' require_relative 'window_deck'
@deck_window = Window_Deck.new @deck_window = Window_Deck.new
end end
def refresh_interval def refresh_interval
5 5
end end
def show_chat_self def show_chat_self
false false
end end
end end
#encoding: UTF-8 #encoding: UTF-8
load 'lib/iduel/window_login.rb' load 'lib/iduel/window_login.rb'
require 'open-uri' require 'open-uri'
class Iduel < Game class Iduel < Game
Version = "20110131" Version = "20110131"
Server = "iduel.ocgsoft.cn" Server = "iduel.ocgsoft.cn"
Register_Url = 'http://www.duelcn.com/member.php?mod=join_id' Register_Url = 'http://www.duelcn.com/member.php?mod=join_id'
Port = 38522 Port = 38522
RS = "¢" RS = "¢"
attr_accessor :session attr_accessor :session
attr_accessor :key attr_accessor :key
def initialize def initialize
super super
require 'digest/md5' require 'digest/md5'
load 'lib/iduel/action.rb' load 'lib/iduel/action.rb'
load 'lib/iduel/event.rb' load 'lib/iduel/event.rb'
load 'lib/iduel/user.rb' load 'lib/iduel/user.rb'
load 'lib/iduel/replay.rb' load 'lib/iduel/replay.rb'
end end
def rename def rename
##8|241019,测试改昵称,5b58559aaf8869282fe3cb9585ffa909¢ ##8|241019,测试改昵称,5b58559aaf8869282fe3cb9585ffa909¢
#$N|iDuel系统,您的改名请求已经提交,重新登录后即可看到效果。¢ #$N|iDuel系统,您的改名请求已经提交,重新登录后即可看到效果。¢
end end
def login(username, password) def login(username, password)
connect connect
md5 = Digest::MD5.hexdigest(password) md5 = Digest::MD5.hexdigest(password)
send(0, username, md5, checknum("LOGINMSG", username, md5), Version) send(0, username, md5, checknum("LOGINMSG", username, md5), Version)
end end
def refresh def refresh
send(1, @key, checknum("UPINFOMSG", @session)) send(1, @key, checknum("UPINFOMSG", @session))
end end
def host(name, password="", lv=0, color = 0) def host(name, password="", lv=0, color = 0)
end end
def host(room_name, room_config) def host(room_name, room_config)
password = "" password = ""
color = 0 color = 0
lv = 0 lv = 0
send(6, @key, room_name, password, checknum("JOINROOMMSG", @session + room_name + password + "0"), 0, color, lv, 0, 0, 0) #TODO:v.ak, v.al send(6, @key, room_name, password, checknum("JOINROOMMSG", @session + room_name + password + "0"), 0, color, lv, 0, 0, 0) #TODO:v.ak, v.al
end end
def join(room, password="") def join(room, password="")
send(6, @key, room.id, password, checknum("JOINROOMMSG", @session + room.id.to_s + password + "1"),1) send(6, @key, room.id, password, checknum("JOINROOMMSG", @session + room.id.to_s + password + "1"),1)
end end
def watch(room, password="") def watch(room, password="")
send(5, @key, room.id, password, checknum("WATCHROOMMSG", "#{@session}#{room.id}#{password}")) send(5, @key, room.id, password, checknum("WATCHROOMMSG", "#{@session}#{room.id}#{password}"))
end end
def leave def leave
return unless @room return unless @room
if @room.include? @user if @room.include? @user
send(10, @key, room.id, checknum("QROOM", @session + room.id.to_s)) send(10, @key, room.id, checknum("QROOM", @session + room.id.to_s))
else else
send(9, @key, checknum("QUITWATCHROOM", @session)) send(9, @key, checknum("QUITWATCHROOM", @session))
end end
end end
def action(action) def action(action)
send(2, "#{checknum("RMSG", @session)}@#{@key}", "#{action.escape}▊▊▊mycard") #消息校验字串,为了防止由于mycard开源造成外挂泛滥扰乱正常iduel秩序,这里不模仿iduel计算校验字串,直接发送mycard供iduel识别 send(2, "#{checknum("RMSG", @session)}@#{@key}", "#{action.escape}▊▊▊mycard") #消息校验字串,为了防止由于mycard开源造成外挂泛滥扰乱正常iduel秩序,这里不模仿iduel计算校验字串,直接发送mycard供iduel识别
end end
def exit def exit
@recv.exit if @recv @recv.exit if @recv
if @conn if @conn
leave leave
send(11, @key, checknum("ULO", "#{@session}")) send(11, @key, checknum("ULO", "#{@session}"))
@conn.close @conn.close
@conn = nil @conn = nil
end end
super super
end end
def recv(info) def recv(info)
if info.nil? if info.nil?
@conn.close @conn.close
@conn = nil @conn = nil
$log.error 'socket已中断' $log.error 'socket已中断'
Game_Event.push Game_Event::Error.parse(0) Game_Event.push Game_Event::Error.parse(0)
else else
info.chomp!(RS) info.chomp!(RS)
info.delete!("\r") info.delete!("\r")
$log.info ">> #{info}" $log.info ">> #{info}"
Game_Event.push Game_Event.parse info Game_Event.push Game_Event.parse info
end end
end end
#def qroom(room) #def qroom(room)
# send(10, @key, room.id, checknum("QROOM", @session + room.id.to_s)) # send(10, @key, room.id, checknum("QROOM", @session + room.id.to_s))
#end #end
def chat(chatmessage) def chat(chatmessage)
msg = chatmessage.message.gsub(",", "@@@@") msg = chatmessage.message.gsub(",", "@@@@")
case chatmessage.channel case chatmessage.channel
when :lobby when :lobby
send(4, @key, msg, checknum("CHATP", @session)) send(4, @key, msg, checknum("CHATP", @session))
when User #私聊 when User #私聊
send(3, @key, "#{chatmessage.channel.name}(#{chatmessage.channel.id})", msg, checknum("CHATX", @session + "X" + "#{chatmessage.channel.name}(#{chatmessage.channel.id})")) send(3, @key, "#{chatmessage.channel.name}(#{chatmessage.channel.id})", msg, checknum("CHATX", @session + "X" + "#{chatmessage.channel.name}(#{chatmessage.channel.id})"))
when Room #房间消息:向双方分别私聊 when Room #房间消息:向双方分别私聊
channel = chatmessage.channel channel = chatmessage.channel
chatmessage.channel = channel.player1 chatmessage.channel = channel.player1
chat chatmessage chat chatmessage
if channel.player2 if channel.player2
chatmessage.channel = channel.player2 chatmessage.channel = channel.player2
chat chatmessage chat chatmessage
end end
chatmessage.channel = channel chatmessage.channel = channel
end end
#4|241019,test,2368c6b89b3e2eedb92e1b624a2a157c #4|241019,test,2368c6b89b3e2eedb92e1b624a2a157c
end end
def get_friends def get_friends
$config['iDuel']['friends'] ||= [] $config['iDuel']['friends'] ||= []
$config['iDuel']['friends'].each {|id|User.new(id).friend = true} $config['iDuel']['friends'].each {|id|User.new(id).friend = true}
Thread.new do Thread.new do
begin begin
open("http://www.duelcn.com/home.php?mod=space&uid=#{@user.id-100000}&do=friend&view=me&from=space") do |file| open("http://www.duelcn.com/home.php?mod=space&uid=#{@user.id-100000}&do=friend&view=me&from=space") do |file|
$config['iDuel']['friends'].each {|id|User.new(id).friend = false} $config['iDuel']['friends'].each {|id|User.new(id).friend = false}
$config['iDuel']['friends'].clear $config['iDuel']['friends'].clear
file.set_encoding "GBK", "UTF-8" file.set_encoding "GBK", "UTF-8"
file.read.scan(/<a href="home.php\?mod=space&amp;uid=(\d+)" title=".*" target="_blank">.*<\/a>/) do |uid, others| file.read.scan(/<a href="home.php\?mod=space&amp;uid=(\d+)" title=".*" target="_blank">.*<\/a>/) do |uid, others|
id = uid.to_i + 100000 id = uid.to_i + 100000
User.new(id).friend = true User.new(id).friend = true
$config['iDuel']['friends'] << id $config['iDuel']['friends'] << id
end end
Config.save Config.save
end end
rescue Exception => exception rescue Exception => exception
$log.error('读取好友信息') {[exception.inspect, *exception.backtrace].collect{|str|str.encode("UTF-8")}.join("\n")} $log.error('读取好友信息') {[exception.inspect, *exception.backtrace].collect{|str|str.encode("UTF-8")}.join("\n")}
end end
end end
end end
def show_chat_self def show_chat_self
true true
end end
private private
def connect def connect
require 'socket' require 'socket'
begin begin
@conn = TCPSocket.new(Server, Port) #TODO: 阻塞优化,注意login。下面注释掉的两句实现connect无阻塞,但是login依然会阻塞所以只优化这里没有意义 @conn = TCPSocket.new(Server, Port) #TODO: 阻塞优化,注意login。下面注释掉的两句实现connect无阻塞,但是login依然会阻塞所以只优化这里没有意义
#@conn = Socket.new(:INET, :STREAM) #@conn = Socket.new(:INET, :STREAM)
@conn.set_encoding "GBK", "UTF-8", :invalid => :replace, :undef => :replace @conn.set_encoding "GBK", "UTF-8", :invalid => :replace, :undef => :replace
Thread.abort_on_exception=true Thread.abort_on_exception=true
@recv = Thread.new do @recv = Thread.new do
begin begin
#@conn.connect Socket.pack_sockaddr_in(Port, Server) #@conn.connect Socket.pack_sockaddr_in(Port, Server)
recv @conn.gets(RS) while @conn recv @conn.gets(RS) while @conn
rescue => exception rescue => exception
$log.error('iduel-connect-1') {[exception.inspect, *exception.backtrace].collect{|str|str.encode("UTF-8")}.join("\n")} $log.error('iduel-connect-1') {[exception.inspect, *exception.backtrace].collect{|str|str.encode("UTF-8")}.join("\n")}
Game_Event.push Game_Event::Error.new(exception.class.to_s, exception.message) Game_Event.push Game_Event::Error.new(exception.class.to_s, exception.message)
ensure ensure
self.exit self.exit
end end
end end
rescue => exception rescue => exception
$log.error('iduel-connect-2') {[exception.inspect, *exception.backtrace].collect{|str|str.encode("UTF-8")}.join("\n")} $log.error('iduel-connect-2') {[exception.inspect, *exception.backtrace].collect{|str|str.encode("UTF-8")}.join("\n")}
Game_Event.push Game_Event::Error.new("网络错误", "连接服务器失败") Game_Event.push Game_Event::Error.new("网络错误", "连接服务器失败")
end end
end end
def checknum(head, *args) def checknum(head, *args)
Digest::MD5.hexdigest("[#{head}]_#{args.join('_')}_SCNERO".gsub("\n", "\r\n").encode("GBK")) Digest::MD5.hexdigest("[#{head}]_#{args.join('_')}_SCNERO".gsub("\n", "\r\n").encode("GBK"))
end end
def send(head, *args) def send(head, *args)
return unless @conn return unless @conn
info = "##{head.to_s(16).upcase}|#{args.join(',')}" + RS info = "##{head.to_s(16).upcase}|#{args.join(',')}" + RS
$log.info "<< #{info}" $log.info "<< #{info}"
info.gsub!("\n", "\r\n") info.gsub!("\n", "\r\n")
(@conn.write info) rescue Game_Event.push Game_Event::Error.new($!.class.to_s, $!.message) (@conn.write info) rescue Game_Event.push Game_Event::Error.new($!.class.to_s, $!.message)
end end
def self.get_announcements def self.get_announcements
#公告 #公告
$config['iDuel']['announcements'] ||= [Announcement.new("正在读取公告...", nil, nil)] $config['iDuel']['announcements'] ||= [Announcement.new("正在读取公告...", nil, nil)]
Thread.new do Thread.new do
begin begin
open('http://www.duelcn.com/topic-Announce.html') do |file| open('http://www.duelcn.com/topic-Announce.html') do |file|
announcements = [] announcements = []
file.read.scan(/<li><a href="(.*?)" title="(.*?)" target="_blank">/).each do |url, title| file.read.scan(/<li><a href="(.*?)" title="(.*?)" target="_blank">/).each do |url, title|
announcements << Announcement.new(title.encode("UTF-8"), "http://www.duelcn.com/#{url}", nil) announcements << Announcement.new(title.encode("UTF-8"), "http://www.duelcn.com/#{url}", nil)
end end
$config['iDuel']['announcements'].replace announcements $config['iDuel']['announcements'].replace announcements
Config.save Config.save
end end
rescue Exception => exception rescue Exception => exception
$log.error('公告') {[exception.inspect, *exception.backtrace].collect{|str|str.encode("UTF-8")}.join("\n")} $log.error('公告') {[exception.inspect, *exception.backtrace].collect{|str|str.encode("UTF-8")}.join("\n")}
end end
end end
end end
get_announcements get_announcements
end end
class Window_Login class Window_Login
def clicked def clicked
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
$config[$config['game']]['password'] = @remember_password.checked? ? @password_inputbox.value : nil $config[$config['game']]['password'] = @remember_password.checked? ? @password_inputbox.value : nil
Config.save Config.save
$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
Dialog.web Iduel::Register_Url Dialog.web Iduel::Register_Url
@last_clicked = Time.now @last_clicked = Time.now
when :replay when :replay
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
end end
@last_clicked = Time.now @last_clicked = Time.now
end end
end end
end end
\ No newline at end of file
#!/usr/bin/env ruby #!/usr/bin/env ruby
begin begin
Windows = RUBY_PLATFORM["win"] || RUBY_PLATFORM["ming"] Windows = RUBY_PLATFORM["win"] || RUBY_PLATFORM["ming"]
Thread.abort_on_exception = true Thread.abort_on_exception = true
require_relative 'resolution' require_relative 'resolution'
require_relative 'announcement' require_relative 'announcement'
require_relative 'config' require_relative 'config'
require_relative 'association' require_relative 'association'
#读取配置文件 #读取配置文件
$config = Config.load $config = Config.load
Config.save Config.save
#读取命令行参数 #读取命令行参数
log = "log.log" log = "log.log"
log_level = "INFO" log_level = "INFO"
profile = nil profile = nil
ARGV.each do |arg| ARGV.each do |arg|
arg = arg.dup.force_encoding("UTF-8") arg = arg.dup.force_encoding("UTF-8")
arg.force_encoding("GBK") unless arg.valid_encoding? arg.force_encoding("GBK") unless arg.valid_encoding?
case arg case arg
when /--log=(.*)/ when /--log=(.*)/
log.replace $1 log.replace $1
when /--log-level=(.*)/ when /--log-level=(.*)/
log_level.replace $1 log_level.replace $1
when /--profile=(.*)/ when /--profile=(.*)/
profile = $1 profile = $1
when /^mycard:.*|\.ydk$|\.yrp$|\.deck$/ when /^mycard:.*|\.ydk$|\.yrp$|\.deck$/
require_relative 'quickstart' require_relative 'quickstart'
$scene = false $scene = false
when /register_association/ when /register_association/
Association.register Association.register
$scene = false $scene = false
end end
end end
unless $scene == false unless $scene == false
#加载文件 #加载文件
require 'logger' require 'logger'
require 'sdl' require 'sdl'
include SDL include SDL
require_relative 'dialog' require_relative 'dialog'
require_relative 'graphics' require_relative 'graphics'
require_relative 'window' require_relative 'window'
require_relative 'widget_msgbox' require_relative 'widget_msgbox'
#日志 #日志
if log == "STDOUT" #调试用 if log == "STDOUT" #调试用
log = STDOUT log = STDOUT
end end
$log = Logger.new(log) $log = Logger.new(log)
$log.level = Logger.const_get log_level $log.level = Logger.const_get log_level
#性能分析 #性能分析
if profile if profile
if profile == "STDOUT" if profile == "STDOUT"
profile = STDOUT profile = STDOUT
else else
profile = open(profile, 'w') profile = open(profile, 'w')
end end
require 'profiler' require 'profiler'
RubyVM::InstructionSequence.compile_option = { RubyVM::InstructionSequence.compile_option = {
:trace_instruction => true, :trace_instruction => true,
:specialized_instruction => false :specialized_instruction => false
} }
Profiler__::start_profile Profiler__::start_profile
end end
SDL::Event::APPMOUSEFOCUS = 1 SDL::Event::APPMOUSEFOCUS = 1
SDL::Event::APPINPUTFOCUS = 2 SDL::Event::APPINPUTFOCUS = 2
SDL::Event::APPACTIVE = 4 SDL::Event::APPACTIVE = 4
SDL.putenv ("SDL_VIDEO_CENTERED=1"); SDL.putenv ("SDL_VIDEO_CENTERED=1");
SDL.init(INIT_VIDEO) SDL.init(INIT_VIDEO)
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))
TTF.init TTF.init
#声音 #声音
begin begin
SDL.init(INIT_AUDIO) SDL.init(INIT_AUDIO)
Mixer.open(Mixer::DEFAULT_FREQUENCY, Mixer::DEFAULT_FORMAT, Mixer::DEFAULT_CHANNELS, 1536) Mixer.open(Mixer::DEFAULT_FREQUENCY, Mixer::DEFAULT_FORMAT, Mixer::DEFAULT_CHANNELS, 1536)
Mixer.set_volume_music(60) Mixer.set_volume_music(60)
rescue rescue
nil nil
end end
#标题场景 #标题场景
require_relative 'scene_title' require_relative 'scene_title'
$scene = Scene_Title.new $scene = Scene_Title.new
#自动更新, 加载放到SDL前面会崩, 原因不明 #自动更新, 加载放到SDL前面会崩, 原因不明
require_relative 'update' require_relative 'update'
Update.start Update.start
WM::set_caption("MyCard v#{Update::Version}", "MyCard") WM::set_caption("MyCard v#{Update::Version}", "MyCard")
#文件关联 #文件关联
Association.start Association.start
#初始化完毕 #初始化完毕
$log.info("main") { "初始化成功" } $log.info("main") { "初始化成功" }
end end
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") }
$scene = false $scene = false
end end
#主循环 #主循环
begin 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].collect { |str| str.force_encoding("UTF-8") }.join("\n") } $log.fatal($1) { [exception.inspect, *exception.backtrace].collect { |str| str.force_encoding("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
retry retry
ensure ensure
if profile if profile
Profiler__::print_profile(profile) Profiler__::print_profile(profile)
profile.close profile.close
end end
$log.close rescue nil $log.close rescue nil
end end
\ No newline at end of file
#============================================================================== #==============================================================================
# 鈻�Scene_Title # 鈻�Scene_Title
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
# 銆�itle # 銆�itle
#============================================================================== #==============================================================================
class Picture < Image class Picture < Image
@load_path = "graphics/picture" @load_path = "graphics/picture"
end end
#encoding: UTF-8 #encoding: UTF-8
#============================================================================== #==============================================================================
# ■ Scene_Base # ■ Scene_Base
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
#  游戏中全部画面的超级类。 #  游戏中全部画面的超级类。
#============================================================================== #==============================================================================
require_relative 'fpstimer' require_relative 'fpstimer'
require_relative 'game' require_relative 'game'
require_relative 'window_bgm' require_relative 'window_bgm'
require 'ogginfo' require 'ogginfo'
require_relative 'widget_inputbox' require_relative 'widget_inputbox'
class Scene class Scene
attr_reader :windows attr_reader :windows
attr_reader :background attr_reader :background
@@fpstimer = FPSTimer.new @@fpstimer = FPSTimer.new
@@last_bgm = @@bgm = nil @@last_bgm = @@bgm = nil
#-------------------------------------------------------------------------- #--------------------------------------------------------------------------
# ● 主处理 # ● 主处理
#-------------------------------------------------------------------------- #--------------------------------------------------------------------------
def initialize def initialize
@background = nil @background = nil
@windows = [] @windows = []
@active_window = nil @active_window = nil
@font = TTF.open('fonts/wqy-microhei.ttc', 16) @font = TTF.open('fonts/wqy-microhei.ttc', 16)
end end
def main def main
start start
while $scene == self while $scene == self
update update
@@fpstimer.wait_frame{draw} @@fpstimer.wait_frame{draw}
end end
terminate terminate
end end
def draw def draw
if @background if @background
$screen.put(@background,0,0) $screen.put(@background,0,0)
else else
$screen.fill_rect(0, 0, $screen.w, $screen.h, 0x000000) $screen.fill_rect(0, 0, $screen.w, $screen.h, 0x000000)
end end
@windows.each do |window| @windows.each do |window|
window.draw($screen) window.draw($screen)
end end
if Update.status if Update.status
@font.draw_blended_utf8($screen, Update.status, 0, 0, 0xFF, 0xFF, 0xFF) @font.draw_blended_utf8($screen, Update.status, 0, 0, 0xFF, 0xFF, 0xFF)
else else
@font.draw_blended_utf8($screen, "%.1f" % @@fpstimer.real_fps, 0, 0, 0xFF, 0xFF, 0xFF) @font.draw_blended_utf8($screen, "%.1f" % @@fpstimer.real_fps, 0, 0, 0xFF, 0xFF, 0xFF)
end end
$screen.update_rect(0,0,0,0) $screen.update_rect(0,0,0,0)
end end
#-------------------------------------------------------------------------- #--------------------------------------------------------------------------
# ● 开始处理 # ● 开始处理
#-------------------------------------------------------------------------- #--------------------------------------------------------------------------
def start def start
if $config['bgm'] and @@last_bgm != bgm and SDL.inited_system(INIT_AUDIO) != 0 and File.file? "audio/bgm/#{bgm}" if $config['bgm'] and @@last_bgm != bgm and SDL.inited_system(INIT_AUDIO) != 0 and File.file? "audio/bgm/#{bgm}"
@@bgm.destroy if @@bgm @@bgm.destroy if @@bgm
@@bgm = Mixer::Music.load "audio/bgm/#{bgm}" @@bgm = Mixer::Music.load "audio/bgm/#{bgm}"
Mixer.fade_in_music(@@bgm, -1, 800) Mixer.fade_in_music(@@bgm, -1, 800)
title = OggInfo.new("audio/bgm/#{bgm}").tag["title"] title = OggInfo.new("audio/bgm/#{bgm}").tag["title"]
@bgm_window = Window_BGM.new title if title and !title.empty? @bgm_window = Window_BGM.new title if title and !title.empty?
@@last_bgm = bgm @@last_bgm = bgm
end end
end end
def bgm def bgm
"title.ogg" "title.ogg"
end end
def last_bgm def last_bgm
@@last_bgm @@last_bgm
end end
def last_bgm=(bgm) def last_bgm=(bgm)
@@last_bgm = bgm @@last_bgm = bgm
end end
def refresh_rect(x, y, width, height, background=@background, ox=0,oy=0) def refresh_rect(x, y, width, height, background=@background, ox=0,oy=0)
Surface.blit(background,x+ox,y+oy,width,height,$screen,x,y) Surface.blit(background,x+ox,y+oy,width,height,$screen,x,y)
yield yield
$screen.update_rect(x, y, width, height) $screen.update_rect(x, y, width, height)
end end
#-------------------------------------------------------------------------- #--------------------------------------------------------------------------
# ● 执行渐变 # ● 执行渐变
#-------------------------------------------------------------------------- #--------------------------------------------------------------------------
def perform_transition def perform_transition
Graphics.transition(10) Graphics.transition(10)
end end
#-------------------------------------------------------------------------- #--------------------------------------------------------------------------
# ● 开始後处理 # ● 开始後处理
#-------------------------------------------------------------------------- #--------------------------------------------------------------------------
def post_start def post_start
end end
#-------------------------------------------------------------------------- #--------------------------------------------------------------------------
# ● 更新画面 # ● 更新画面
#-------------------------------------------------------------------------- #--------------------------------------------------------------------------
def update def update
@bgm_window.update if @bgm_window and !@bgm_window.destroyed? @bgm_window.update if @bgm_window and !@bgm_window.destroyed?
while event = Event.poll while event = Event.poll
handle(event) handle(event)
end end
#要不要放到一个Scene_Game里来处理这个? #要不要放到一个Scene_Game里来处理这个?
while event = Game_Event.poll while event = Game_Event.poll
handle_game(event) handle_game(event)
end end
end end
def handle(event) def handle(event)
case event case event
when Event::MouseMotion when Event::MouseMotion
update_active_window(event.x, event.y) update_active_window(event.x, event.y)
when Event::MouseButtonDown when Event::MouseButtonDown
case event.button case event.button
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) if !(@active_window.is_a? Widget_InputBox)
Widget_InputBox.focus = false Widget_InputBox.focus = false
end 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
when Event::MouseButtonUp when Event::MouseButtonUp
case event.button case event.button
when Mouse::BUTTON_LEFT when Mouse::BUTTON_LEFT
update_active_window(event.x, event.y) update_active_window(event.x, event.y)
@active_window.mouseleftbuttonup if @active_window @active_window.mouseleftbuttonup if @active_window
end end
when Event::KeyDown when Event::KeyDown
case event.sym case event.sym
when Key::RETURN when Key::RETURN
if event.mod & Key::MOD_ALT != 0 if event.mod & Key::MOD_ALT != 0
$config['screen']['fullscreen'] = !$config['screen']['fullscreen'] $config['screen']['fullscreen'] = !$config['screen']['fullscreen']
$screen.destroy $screen.destroy
style = HWSURFACE style = HWSURFACE
style |= FULLSCREEN if $config['screen']["fullscreen"] style |= FULLSCREEN if $config['screen']["fullscreen"]
$screen = Screen.open($config['screen']["width"], $config['screen']["height"], 0, style) $screen = Screen.open($config['screen']["width"], $config['screen']["height"], 0, style)
Config.save Config.save
end end
when Key::F12 when Key::F12
$scene = Scene_Title.new $scene = Scene_Title.new
else else
#$log.info('unhandled event'){event.inspect} #$log.info('unhandled event'){event.inspect}
end end
when Event::Quit when Event::Quit
$scene = nil $scene = nil
when Event::Active when Event::Active
if (event.state & Event::APPINPUTFOCUS) != 0 if (event.state & Event::APPINPUTFOCUS) != 0
Widget_InputBox.focus = event.gain Widget_InputBox.focus = event.gain
end end
else else
#$log.info('unhandled event'){event.inspect} #$log.info('unhandled event'){event.inspect}
end end
end end
def handle_game(event) def handle_game(event)
case event case event
when Game_Event::Error when Game_Event::Error
if event.fatal if event.fatal
Widget_Msgbox.new(event.title, event.message, :ok => "确定"){$game.exit if $game;$scene = Scene_Login.new} Widget_Msgbox.new(event.title, event.message, :ok => "确定"){$game.exit if $game;$scene = Scene_Login.new}
else else
Widget_Msgbox.new(event.title, event.message, :ok => "确定") Widget_Msgbox.new(event.title, event.message, :ok => "确定")
end end
else else
$log.debug('未处理的游戏事件'){event.inspect} $log.debug('未处理的游戏事件'){event.inspect}
end end
end end
#-------------------------------------------------------------------------- #--------------------------------------------------------------------------
# ● 结束前处理 # ● 结束前处理
#-------------------------------------------------------------------------- #--------------------------------------------------------------------------
def pre_terminate def pre_terminate
end end
#-------------------------------------------------------------------------- #--------------------------------------------------------------------------
# ● 结束处理 # ● 结束处理
#-------------------------------------------------------------------------- #--------------------------------------------------------------------------
def terminate def terminate
self.windows.each{|window|window.destroy} self.windows.each{|window|window.destroy}
end end
def update_active_window(x, y) def update_active_window(x, y)
self.windows.reverse.each do |window| self.windows.reverse.each do |window|
if window.include?(x, y) && window.visible if window.include?(x, y) && window.visible
if window != @active_window if window != @active_window
@active_window.lostfocus(window) if @active_window and !@active_window.destroyed? @active_window.lostfocus(window) if @active_window and !@active_window.destroyed?
@active_window = window @active_window = window
end end
@active_window.mousemoved(x, y) @active_window.mousemoved(x, y)
return @active_window return @active_window
end end
end end
if @active_window and !@active_window.destroyed? if @active_window and !@active_window.destroyed?
@active_window.lostfocus @active_window.lostfocus
@active_window = nil @active_window = nil
end end
end end
end end
#encoding: UTF-8 #encoding: UTF-8
#============================================================================== #==============================================================================
# Scene_Duel # Scene_Duel
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
# 决斗盘的场景 # 决斗盘的场景
#============================================================================== #==============================================================================
class Scene_Duel < Scene class Scene_Duel < Scene
require_relative 'window_lp' require_relative 'window_lp'
require_relative 'window_phases' require_relative 'window_phases'
require_relative 'window_field' require_relative 'window_field'
require_relative 'window_fieldback' require_relative 'window_fieldback'
require_relative 'card' require_relative 'card'
require_relative 'deck' require_relative 'deck'
require_relative 'action' require_relative 'action'
require_relative 'replay' require_relative 'replay'
require_relative 'game_card' require_relative 'game_card'
require_relative 'game_field' require_relative 'game_field'
require_relative 'window_chat' require_relative 'window_chat'
attr_reader :cardinfo_window attr_reader :cardinfo_window
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
def initialize(room, deck=nil) def initialize(room, deck=nil)
super() super()
@room = room @room = room
@deck = deck @deck = deck
end end
def start def start
WM::set_caption("MyCard v#{Update::Version} - #{$config['game']} - #{$game.user.name}(#{$game.user.id}) - #{@room.name}(#{@room.id})", "MyCard") WM::set_caption("MyCard v#{Update::Version} - #{$config['game']} - #{$game.user.name}(#{$game.user.id}) - #{@room.name}(#{@room.id})", "MyCard")
@background = Surface.load("graphics/field/main.png").display_format @background = Surface.load("graphics/field/main.png").display_format
Surface.blit(@background, 0, 0, 0, 0, $screen, 0, 0) Surface.blit(@background, 0, 0, 0, 0, $screen, 0, 0)
init_game init_game
init_replay init_replay
@phases_window = Window_Phases.new(122, 356) @phases_window = Window_Phases.new(122, 356)
@fieldback_window = Window_FieldBack.new(131,173) @fieldback_window = Window_FieldBack.new(131,173)
@cardinfo_window = Window_CardInfo.new(715, 0) @cardinfo_window = Window_CardInfo.new(715, 0)
@player_field_window = Window_Field.new(2, 397, $game.player_field, true) @player_field_window = Window_Field.new(2, 397, $game.player_field, true)
@opponent_field_window = Window_Field.new(2, 56, $game.opponent_field, false) @opponent_field_window = Window_Field.new(2, 56, $game.opponent_field, false)
@player_lp_window = Window_LP.new(0,0, @room.player1, true) @player_lp_window = Window_LP.new(0,0, @room.player1, true)
@opponent_lp_window = Window_LP.new(360,0, @room.player2, false) @opponent_lp_window = Window_LP.new(360,0, @room.player2, false)
@join_se = Mixer::Wave.load("audio/se/join.ogg") if SDL.inited_system(INIT_AUDIO) != 0 @join_se = Mixer::Wave.load("audio/se/join.ogg") if SDL.inited_system(INIT_AUDIO) != 0
create_action_window create_action_window
create_chat_window create_chat_window
super super
end end
def bgm def bgm
"duel.ogg" "duel.ogg"
end 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
def create_chat_window def create_chat_window
@background.fill_rect(@cardinfo_window.x, @cardinfo_window.height, 1024-@cardinfo_window.x, 768-@cardinfo_window.height,0xFFFFFFFF) @background.fill_rect(@cardinfo_window.x, @cardinfo_window.height, 1024-@cardinfo_window.x, 768-@cardinfo_window.height,0xFFFFFFFF)
@chat_window = Window_Chat.new(@cardinfo_window.x, @cardinfo_window.height, 1024-@cardinfo_window.x, 768-@cardinfo_window.height){|text|chat(text)} @chat_window = Window_Chat.new(@cardinfo_window.x, @cardinfo_window.height, 1024-@cardinfo_window.x, 768-@cardinfo_window.height){|text|chat(text)}
@chat_window.channel = @room @chat_window.channel = @room
end end
def chat(text) def chat(text)
action Action::Chat.new(true, text) action Action::Chat.new(true, text)
end end
def init_replay def init_replay
@replay = Replay.new @replay = Replay.new
end end
def save_replay def save_replay
#@replay.save if @replay #功能尚不可用 #@replay.save if @replay #功能尚不可用
end end
def init_game def init_game
$game.player_field = Game_Field.new @deck $game.player_field = Game_Field.new @deck
$game.opponent_field = Game_Field.new $game.opponent_field = Game_Field.new
$game.turn_player = true # $game.turn_player = true #
$game.turn = 0 $game.turn = 0
end end
def change_phase(phase) def change_phase(phase)
action Action::ChangePhase.new(true, phase) action Action::ChangePhase.new(true, phase)
if phase == :EP and if phase == :EP and
action Action::TurnEnd.new(true, $game.player_field, $game.turn_player ? $game.turn : $game.turn.next) action Action::TurnEnd.new(true, $game.player_field, $game.turn_player ? $game.turn : $game.turn.next)
end end
end end
def reset def reset
action Action::Reset.new(true) action Action::Reset.new(true)
end end
def first_to_go def first_to_go
action Action::FirstToGo.new(true) action Action::FirstToGo.new(true)
end end
def handle(event) def handle(event)
case event case event
when Event::MouseButtonDown when Event::MouseButtonDown
case event.button case event.button
when Mouse::BUTTON_RIGHT when Mouse::BUTTON_RIGHT
if @player_field_window.action_window if @player_field_window.action_window
@player_field_window.action_window.next @player_field_window.action_window.next
end end
else else
super super
end end
when Event::KeyDown when Event::KeyDown
case event.sym case event.sym
when Key::F1 when Key::F1
action Action::Shuffle.new action Action::Shuffle.new
@player_field_window.refresh @player_field_window.refresh
when Key::F2 when Key::F2
first_to_go first_to_go
@player_field_window.refresh @player_field_window.refresh
when Key::F3 when Key::F3
action Action::Dice.new(true) action Action::Dice.new(true)
when Key::F5 when Key::F5
reset reset
@player_field_window.refresh @player_field_window.refresh
when Key::F10 when Key::F10
$game.leave $game.leave
else else
super super
end end
else else
super super
end end
end end
def action(action) def action(action)
$game.action action# if @from_player $game.action action# if @from_player
Game_Event.push Game_Event::Action.new(action) Game_Event.push Game_Event::Action.new(action)
end end
def handle_game(event) def handle_game(event)
case event case event
when Game_Event::Chat when Game_Event::Chat
@chat_window.add event.chatmessage @chat_window.add event.chatmessage
when Game_Event::Action when Game_Event::Action
if event.action.instance_of?(Action::Reset) and event.action.from_player if event.action.instance_of?(Action::Reset) and event.action.from_player
save_replay save_replay
init_replay init_replay
end end
@replay.add event.str @replay.add event.str
str = event.str str = event.str
if str =~ /^\[\d+\] (.*)$/m if str =~ /^\[\d+\] (.*)$/m
str = $1 str = $1
end end
if str =~ /^(?:●|◎)→(.*)$/m if str =~ /^(?:●|◎)→(.*)$/m
str = $1 str = $1
end end
user = if $game.room.player2 == $game.user user = if $game.room.player2 == $game.user
event.action.from_player ? $game.room.player2 : $game.room.player1 event.action.from_player ? $game.room.player2 : $game.room.player1
else else
event.action.from_player ? $game.room.player1 : $game.room.player2 event.action.from_player ? $game.room.player1 : $game.room.player2
end end
@chat_window.add ChatMessage.new(user, str, $game.room) @chat_window.add ChatMessage.new(user, str, $game.room)
event.action.run event.action.run
refresh refresh
when Game_Event::Leave when Game_Event::Leave
$scene = Scene_Lobby.new $scene = Scene_Lobby.new
when Game_Event::Join when Game_Event::Join
$game.room = event.room $game.room = event.room
@player_lp_window.player = $game.room.player1 @player_lp_window.player = $game.room.player1
@opponent_lp_window.player = $game.room.player2 @opponent_lp_window.player = $game.room.player2
player = $game.room.player1 == $game.user ? $game.room.player2 : $game.room.player1 player = $game.room.player1 == $game.user ? $game.room.player2 : $game.room.player1
if player if player
notify_send("对手加入房间", "#{player.name}(#{player.id})") notify_send("对手加入房间", "#{player.name}(#{player.id})")
Mixer.play_channel(-1,@join_se,0) if SDL.inited_system(INIT_AUDIO) != 0 Mixer.play_channel(-1,@join_se,0) if SDL.inited_system(INIT_AUDIO) != 0
else else
notify_send("对手离开房间", "对手离开房间") notify_send("对手离开房间", "对手离开房间")
end end
else else
super super
end end
end end
def update def update
@cardinfo_window.update @cardinfo_window.update
@chat_window.update @chat_window.update
super super
end end
def refresh def refresh
@fieldback_window.card = $game.player_field.field[0] && $game.player_field.field[0].card_type == :"场地魔法" && $game.player_field.field[0].position == :attack ? $game.player_field.field[0] : $game.opponent_field.field[0] && $game.opponent_field.field[0].card_type == :"场地魔法" && $game.opponent_field.field[0].position == :attack ? $game.opponent_field.field[0] : nil @fieldback_window.card = $game.player_field.field[0] && $game.player_field.field[0].card_type == :"场地魔法" && $game.player_field.field[0].position == :attack ? $game.player_field.field[0] : $game.opponent_field.field[0] && $game.opponent_field.field[0].card_type == :"场地魔法" && $game.opponent_field.field[0].position == :attack ? $game.opponent_field.field[0] : nil
@player_field_window.refresh @player_field_window.refresh
@opponent_field_window.refresh @opponent_field_window.refresh
@phases_window.player = $game.turn_player @phases_window.player = $game.turn_player
@phases_window.phase = $game.phase @phases_window.phase = $game.phase
@player_lp_window.lp = $game.player_field.lp @player_lp_window.lp = $game.player_field.lp
@opponent_lp_window.lp = $game.opponent_field.lp @opponent_lp_window.lp = $game.opponent_field.lp
end end
def terminate def terminate
unless $scene.is_a? Scene_Lobby or $scene.is_a? Scene_Duel unless $scene.is_a? Scene_Lobby or $scene.is_a? Scene_Duel
$game.exit $game.exit
end end
save_replay save_replay
super super
end end
def notify_send(title, msg) def notify_send(title, msg)
command = "notify-send -i graphics/system/icon.ico #{title} #{msg}" command = "notify-send -i graphics/system/icon.ico #{title} #{msg}"
command = "start ruby/bin/#{command}".encode "GBK" if RUBY_PLATFORM["win"] || RUBY_PLATFORM["ming"] command = "start ruby/bin/#{command}".encode "GBK" if RUBY_PLATFORM["win"] || RUBY_PLATFORM["ming"]
system(command) system(command)
$log.info command $log.info command
end end
end end
\ No newline at end of file
#encoding: UTF-8 #encoding: UTF-8
#============================================================================== #==============================================================================
# Scene_Lobby # Scene_Lobby
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
# 大厅 # 大厅
#============================================================================== #==============================================================================
class Scene_Lobby < Scene class Scene_Lobby < Scene
require_relative 'window_userlist' require_relative 'window_userlist'
require_relative 'window_userinfo' require_relative 'window_userinfo'
require_relative 'window_roomlist' require_relative 'window_roomlist'
require_relative 'window_chat' require_relative 'window_chat'
require_relative 'window_host' require_relative 'window_host'
require_relative 'window_lobbybuttons' require_relative 'window_lobbybuttons'
require_relative 'chatmessage' require_relative 'chatmessage'
require_relative 'scene_duel' require_relative 'scene_duel'
attr_reader :chat_window attr_reader :chat_window
def start def start
WM::set_caption("MyCard v#{Update::Version} - #{$config['game']} - #{$game.user.name}(#{$game.user.id})", "MyCard") WM::set_caption("MyCard v#{Update::Version} - #{$config['game']} - #{$game.user.name}(#{$game.user.id})", "MyCard")
$game.refresh $game.refresh
@background = Graphics.load('lobby', 'background', false) @background = Graphics.load('lobby', 'background', false)
Surface.blit(@background,0,0,0,0,$screen,0,0) Surface.blit(@background,0,0,0,0,$screen,0,0)
@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(748,18) @host_window = Window_LobbyButtons.new(748,18)
@active_window = @roomlist @active_window = @roomlist
@chat_window = Window_Chat.new(313,$config['screen']['height'] - 225,698,212) @chat_window = Window_Chat.new(313,$config['screen']['height'] - 225,698,212)
@count = 0 @count = 0
super super
end end
def bgm def bgm
"lobby.ogg" "lobby.ogg"
end end
def handle(event) def handle(event)
case event case event
when Event::KeyDown when Event::KeyDown
case event.sym case event.sym
when Key::UP when Key::UP
@active_window.cursor_up @active_window.cursor_up
when Key::DOWN when Key::DOWN
@active_window.cursor_down @active_window.cursor_down
when Key::F2 when Key::F2
#@joinroom_msgbox = Widget_Msgbox.new("创建房间", "正在等待对手") #@joinroom_msgbox = Widget_Msgbox.new("创建房间", "正在等待对手")
#$game.host Room.new(0, $game.user.name) #$game.host Room.new(0, $game.user.name)
when Key::F3 when Key::F3
#@joinroom_msgbox = Widget_Msgbox.new("加入房间", "正在加入房间") #@joinroom_msgbox = Widget_Msgbox.new("加入房间", "正在加入房间")
#$game.join 'localhost' #$game.join 'localhost'
when Key::F5 when Key::F5
$game.refresh $game.refresh
when Key::F12 when Key::F12
$game.exit $game.exit
$scene = Scene_Login.new $scene = Scene_Login.new
end end
else else
super super
end end
end end
def handle_game(event) def handle_game(event)
case event case event
when Game_Event::AllUsers when Game_Event::AllUsers
@userlist.items = $game.users @userlist.items = $game.users
when Game_Event::AllRooms when Game_Event::AllRooms
@roomlist.items = $game.rooms @roomlist.items = $game.rooms
when Game_Event::Join when Game_Event::Join
join(event.room) join(event.room)
when Game_Event::Watch when Game_Event::Watch
require_relative 'scene_watch' require_relative 'scene_watch'
$scene = Scene_Watch.new(event.room) $scene = Scene_Watch.new(event.room)
when Game_Event::Chat when Game_Event::Chat
@chat_window.add event.chatmessage @chat_window.add event.chatmessage
else else
super super
end end
end end
def join(room) def join(room)
$scene = Scene_Duel.new(room) $scene = Scene_Duel.new(room)
end end
def update def update
@chat_window.update @chat_window.update
@host_window.update @host_window.update
@roomlist.update @roomlist.update
if @count >= $game.refresh_interval*60 if @count >= $game.refresh_interval*60
$game.refresh $game.refresh
@count = 0 @count = 0
end end
@count += 1 @count += 1
super super
end end
def terminate def terminate
unless $scene.is_a? Scene_Lobby or $scene.is_a? Scene_Duel unless $scene.is_a? Scene_Lobby or $scene.is_a? Scene_Duel
$game.exit $game.exit
end end
end end
end end
\ No newline at end of file
#encoding: UTF-8 #encoding: UTF-8
#============================================================================== #==============================================================================
# ■ Scene_Login # ■ Scene_Login
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
#  login #  login
#============================================================================== #==============================================================================
require_relative 'window_gameselect' require_relative 'window_gameselect'
require_relative 'window_announcements' 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'
class Scene_Login < Scene class Scene_Login < Scene
def start def start
WM::set_caption("MyCard v#{Update::Version}", "MyCard") WM::set_caption("MyCard v#{Update::Version}", "MyCard")
@background = Graphics.load('login', 'background', false) @background = Graphics.load('login', 'background', false)
#====================================================== #======================================================
# We'll pay fpr that soon or later. # We'll pay fpr that soon or later.
#====================================================== #======================================================
if $config['screen']['height'] == 768 if $config['screen']['height'] == 768
@gameselect_window = Window_GameSelect.new(117,269) @gameselect_window = Window_GameSelect.new(117,269)
elsif $config['screen']['height'] == 640 elsif $config['screen']['height'] == 640
@gameselect_window = Window_GameSelect.new(117,134) @gameselect_window = Window_GameSelect.new(117,134)
else else
raise "无法分辨的分辨率" raise "无法分辨的分辨率"
end end
#====================================================== #======================================================
# ENDS HERE # ENDS HERE
#====================================================== #======================================================
super super
end end
def update def update
@gameselect_window.update @gameselect_window.update
super super
end end
def handle_game(event) def handle_game(event)
case event case event
when Game_Event::Login when Game_Event::Login
require_relative 'scene_lobby' require_relative 'scene_lobby'
$scene = Scene_Lobby.new $scene = Scene_Lobby.new
else else
super super
end end
end end
#def terminate #def terminate
# @gameselect_window.destroy # @gameselect_window.destroy
#end #end
end end
\ No newline at end of file
#encoding: UTF-8 #encoding: UTF-8
#============================================================================== #==============================================================================
# Scene_Title # Scene_Title
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
# title # title
#============================================================================== #==============================================================================
require_relative 'scene' require_relative 'scene'
require_relative 'widget_inputbox' require_relative 'widget_inputbox'
require_relative 'window_title' require_relative 'window_title'
BGM = 'title.ogg' BGM = 'title.ogg'
class Scene_Title < Scene class Scene_Title < Scene
def start def start
WM::set_caption("MyCard v#{Update::Version}", "MyCard") WM::set_caption("MyCard v#{Update::Version}", "MyCard")
title = Dir.glob("graphics/titles/title_*.*") title = Dir.glob("graphics/titles/title_*.*")
title = title[rand(title.size)] title = title[rand(title.size)]
@background = Surface.load(title).display_format @background = Surface.load(title).display_format
Surface.blit(@background,0,0,0,0,$screen,0,0) Surface.blit(@background,0,0,0,0,$screen,0,0)
@command_window = Window_Title.new(title["left"] ? 200 : title["right"] ? 600 : 400, $config['screen']['height']/2-100) @command_window = Window_Title.new(title["left"] ? 200 : title["right"] ? 600 : 400, $config['screen']['height']/2-100)
@decision_se = Mixer::Wave.load("audio/se/decision.ogg") if SDL.inited_system(INIT_AUDIO) != 0 @decision_se = Mixer::Wave.load("audio/se/decision.ogg") if SDL.inited_system(INIT_AUDIO) != 0
super super
end end
def clear(x,y,width,height) def clear(x,y,width,height)
Surface.blit(@background,x,y,width,height,$screen,x,y) Surface.blit(@background,x,y,width,height,$screen,x,y)
end end
def determine def determine
return unless @command_window.index return unless @command_window.index
Mixer.play_channel(-1,@decision_se,0) if SDL.inited_system(INIT_AUDIO) != 0 Mixer.play_channel(-1,@decision_se,0) if SDL.inited_system(INIT_AUDIO) != 0
case @command_window.index case @command_window.index
when 0 when 0
require_relative 'scene_login' require_relative 'scene_login'
$scene = Scene_Login.new $scene = Scene_Login.new
when 1 when 1
#require_relative 'scene_single' #require_relative 'scene_single'
require_relative 'widget_msgbox' require_relative 'widget_msgbox'
Widget_Msgbox.new("mycard", "功能未实现", :ok => "确定") Widget_Msgbox.new("mycard", "功能未实现", :ok => "确定")
#Scene_Single.new #Scene_Single.new
when 2 when 2
require_relative 'widget_msgbox' require_relative 'widget_msgbox'
require_relative 'scene_login' require_relative 'scene_login'
require_relative 'deck' require_relative 'deck'
load 'lib/ygocore/game.rb' #TODO:不规范啊不规范 load 'lib/ygocore/game.rb' #TODO:不规范啊不规范
Ygocore.deck_edit Ygocore.deck_edit
when 3 when 3
require_relative 'scene_config' require_relative 'scene_config'
$scene = Scene_Config.new $scene = Scene_Config.new
when 4 when 4
$scene = nil $scene = nil
end end
end end
def terminate def terminate
@command_window.destroy @command_window.destroy
@background.destroy @background.destroy
super super
end end
end end
#encoding: UTF-8 #encoding: UTF-8
#============================================================================== #==============================================================================
# ■ Scene_Watch # ■ Scene_Watch
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
#  观战 #  观战
#============================================================================== #==============================================================================
require_relative 'scene_duel' require_relative 'scene_duel'
class Scene_Watch < Scene_Duel class Scene_Watch < Scene_Duel
def create_action_window def create_action_window
end end
def chat(text) def chat(text)
$game.chat text, $game.room $game.chat text, $game.room
Game_Event.push Game_Event::Action.new(Action::Chat.new(true, text), "#{$game.user}:#{text}") Game_Event.push Game_Event::Action.new(Action::Chat.new(true, text), "#{$game.user}:#{text}")
end end
def action(action) def action(action)
end end
def start def start
super super
#$game.chat "#{$game.user.name}(#{$game.user.id})进入了观战", @room #$game.chat "#{$game.user.name}(#{$game.user.id})进入了观战", @room
end end
def terminate def terminate
#$game.chat "#{$game.user.name}(#{$game.user.id})离开了观战", @room #$game.chat "#{$game.user.name}(#{$game.user.id})离开了观战", @room
end end
def handle_game(event) def handle_game(event)
case event case event
when Game_Event::Leave when Game_Event::Leave
Widget_Msgbox.new("离开房间", "观战结束", :ok => "确定") { $scene = Scene_Lobby.new } Widget_Msgbox.new("离开房间", "观战结束", :ok => "确定") { $scene = Scene_Lobby.new }
else else
super super
end end
end end
end end
require 'open-uri' require 'open-uri'
require "fileutils" require "fileutils"
require_relative 'card' require_relative 'card'
module Update module Update
Version = '0.7.4' Version = '0.7.4'
URL = "http://my-card.in/mycard/update.json?version=#{Version}" URL = "http://my-card.in/mycard/update.json?version=#{Version}"
class <<self class <<self
attr_reader :thumbnails, :images, :status attr_reader :thumbnails, :images, :status
def start def start
Dir.glob("mycard-update-*-*.zip") do |file| Dir.glob("mycard-update-*-*.zip") do |file|
file =~ /mycard-update-(.+?)-(.+?)\.zip/ file =~ /mycard-update-(.+?)-(.+?)\.zip/
if $1 <= Version and $2 > Version if $1 <= Version and $2 > Version
$log.info('安装更新'){file} $log.info('安装更新'){file}
WM::set_caption("MyCard - 正在更新 #{Version} -> #{$2}", "MyCard") WM::set_caption("MyCard - 正在更新 #{Version} -> #{$2}", "MyCard")
require 'zip/zip' require 'zip/zip'
Zip::ZipFile::open(file) do |zip| Zip::ZipFile::open(file) do |zip|
zip.each do |f| zip.each do |f|
if !File.directory?(f.name) if !File.directory?(f.name)
FileUtils.mkdir_p(File.dirname(f.name)) FileUtils.mkdir_p(File.dirname(f.name))
end end
f.extract{true} f.extract{true}
end end
end rescue $log.error('安装更新出错'){file+$!.inspect+$!.backtrace.inspect} end rescue $log.error('安装更新出错'){file+$!.inspect+$!.backtrace.inspect}
Version.replace $2 Version.replace $2
File.delete file File.delete file
@updated = true @updated = true
end end
end end
if @updated if @updated
IO.popen('./mycard') IO.popen('./mycard')
$scene = nil $scene = nil
end end
@images = [] @images = []
@thumbnails = [] @thumbnails = []
@status = '正在检查更新' @status = '正在检查更新'
@updated = false @updated = false
Thread.new do Thread.new do
open(URL) do |file| open(URL) do |file|
require 'json' require 'json'
reply = file.read reply = file.read
$log.info('下载更新-服务器回传'){reply} $log.info('下载更新-服务器回传'){reply}
reply = JSON.parse(reply) reply = JSON.parse(reply)
$log.info('下载更新-解析后'){reply.inspect} $log.info('下载更新-解析后'){reply.inspect}
reply.each do |fil| reply.each do |fil|
name = File.basename fil name = File.basename fil
@status.replace "正在下载更新#{name}" @status.replace "正在下载更新#{name}"
open(fil, 'rb') do |fi| open(fil, 'rb') do |fi|
$log.info('下载完毕'){name} $log.info('下载完毕'){name}
@updated = true @updated = true
open(name, 'wb') do |f| open(name, 'wb') do |f|
f.write fi.read f.write fi.read
end end
end rescue $log.error('下载更新'){'下载更新失败'} end rescue $log.error('下载更新'){'下载更新失败'}
end end
end rescue $log.error('检查更新'){'检查更新失败'} end rescue $log.error('检查更新'){'检查更新失败'}
if @updated if @updated
require_relative 'widget_msgbox' require_relative 'widget_msgbox'
Widget_Msgbox.new('mycard', '下载更新完毕,点击确定重新运行mycard并安装更新', :ok => "确定"){IO.popen('./mycard'); $scene = nil} Widget_Msgbox.new('mycard', '下载更新完毕,点击确定重新运行mycard并安装更新', :ok => "确定"){IO.popen('./mycard'); $scene = nil}
end end
if File.file? "ygocore/cards.cdb" if File.file? "ygocore/cards.cdb"
require 'sqlite3' require 'sqlite3'
db = SQLite3::Database.new( "ygocore/cards.cdb" ) 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.replace @thumbnails @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 end
@thumbnails -= existed_thumbnails @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 end
@images -= existed_images @images -= existed_images
existed_images = [] existed_images = []
if (!@images.empty? or !@thumbnails.empty?) and File.file?("#{Card::PicPath}/1.jpg") if (!@images.empty? or !@thumbnails.empty?) and File.file?("#{Card::PicPath}/1.jpg")
db_mycard = SQLite3::Database.new( "data/data.sqlite" ) db_mycard = SQLite3::Database.new( "data/data.sqlite" )
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" src = "#{Card::PicPath}/#{id}.jpg"
dest = "ygocore/pics/#{number}.jpg" dest = "ygocore/pics/#{number}.jpg"
dest_thumb = "ygocore/pics/thumbnail/#{number}.jpg" dest_thumb = "ygocore/pics/thumbnail/#{number}.jpg"
if File.file?(src) if File.file?(src)
@status.replace "检测到存在iDuel卡图 正在导入 #{id}.jpg" @status.replace "检测到存在iDuel卡图 正在导入 #{id}.jpg"
existed_images << number existed_images << number
if !File.exist?(dest) if !File.exist?(dest)
FileUtils.copy_file(src, dest) FileUtils.copy_file(src, dest)
FileUtils.copy_file(src, dest_thumb) FileUtils.copy_file(src, dest_thumb)
end end
end end
end end
end end
@images -= existed_images @images -= existed_images
@thumbnails -= existed_images @thumbnails -= existed_images
@thumbnails = (@thumbnails & @images) + (@thumbnails - @images) @thumbnails = (@thumbnails & @images) + (@thumbnails - @images)
unless @thumbnails.empty? and @images.empty? unless @thumbnails.empty? and @images.empty?
$log.info('待下载的完整卡图'){@images.inspect} $log.info('待下载的完整卡图'){@images.inspect}
$log.info('待下载的缩略卡图'){@thumbnails.inspect} $log.info('待下载的缩略卡图'){@thumbnails.inspect}
threads = 5.times.collect do threads = 5.times.collect do
thread = Thread.new do thread = Thread.new do
while number = @thumbnails.pop while number = @thumbnails.pop
@status.replace "正在下载缩略卡图 (剩余#{@thumbnails.size}张)" @status.replace "正在下载缩略卡图 (剩余#{@thumbnails.size}张)"
open("http://my-card.in/images/cards/ygocore/thumbnail/#{number}.jpg", 'rb') do |remote| open("http://my-card.in/images/cards/ygocore/thumbnail/#{number}.jpg", 'rb') do |remote|
next if File.file? "ygocore/pics/thumbnail/#{number}.jpg" next if File.file? "ygocore/pics/thumbnail/#{number}.jpg"
#$log.debug('下载缩略卡图'){"http://my-card.in/images/cards/ygocore/thumbnail/#{number}.jpg 到 ygocore/pics/thumbnail/#{number}.jpg" } #$log.debug('下载缩略卡图'){"http://my-card.in/images/cards/ygocore/thumbnail/#{number}.jpg 到 ygocore/pics/thumbnail/#{number}.jpg" }
open("ygocore/pics/thumbnail/#{number}.jpg", 'wb') do |local| open("ygocore/pics/thumbnail/#{number}.jpg", 'wb') do |local|
local.write remote.read local.write remote.read
end end
end rescue $log.error('下载缩略出错'){"http://my-card.in/images/cards/ygocore/thumbnail/#{number}.jpg 到 ygocore/pics/thumbnail/#{number}.jpg" } end rescue $log.error('下载缩略出错'){"http://my-card.in/images/cards/ygocore/thumbnail/#{number}.jpg 到 ygocore/pics/thumbnail/#{number}.jpg" }
end end
while number = @images.pop while number = @images.pop
@status.replace "正在下载完整卡图 (剩余#{@images.size}张)" @status.replace "正在下载完整卡图 (剩余#{@images.size}张)"
#$log.debug('下载完整卡图'){"http://my-card.in/images/cards/ygocore/#{number}.jpg 到 ygocore/pics/#{number}.jpg" } #$log.debug('下载完整卡图'){"http://my-card.in/images/cards/ygocore/#{number}.jpg 到 ygocore/pics/#{number}.jpg" }
open("http://my-card.in/images/cards/ygocore/#{number}.jpg", 'rb') do |remote| open("http://my-card.in/images/cards/ygocore/#{number}.jpg", 'rb') do |remote|
next if File.file? "ygocore/pics/#{number}.jpg" next if File.file? "ygocore/pics/#{number}.jpg"
open("ygocore/pics/#{number}.jpg", 'wb') do |local| open("ygocore/pics/#{number}.jpg", 'wb') do |local|
local.write remote.read local.write remote.read
end end
end rescue $log.error('下载完整卡图出错'){"http://my-card.in/images/cards/ygocore/#{number}.jpg 到 ygocore/pics/#{number}.jpg" } end rescue $log.error('下载完整卡图出错'){"http://my-card.in/images/cards/ygocore/#{number}.jpg 到 ygocore/pics/#{number}.jpg" }
end end
end end
thread.priority = -1 thread.priority = -1
thread thread
end end
threads.each{|thread|thread.join} threads.each{|thread|thread.join}
end end
end rescue $log.error('卡图更新'){'找不到ygocore卡片数据库'} end rescue $log.error('卡图更新'){'找不到ygocore卡片数据库'}
@status = nil @status = nil
end.priority = -1 end.priority = -1
end end
end end
end end
class Window class Window
WLH = 24 WLH = 24
attr_accessor :x, :y, :width, :height, :z, :contents, :visible, :viewport, :background attr_accessor :x, :y, :width, :height, :z, :contents, :visible, :viewport, :background
alias visible? visible alias visible? visible
def initialize(x, y, width, height, z=200) def initialize(x, y, width, height, z=200)
@x = x @x = x
@y = y @y = y
@z = z @z = z
@width = width @width = width
@height = height @height = height
@visible = true @visible = true
#@angle = 0 #@angle = 0
@viewport = [0, 0, @width, @height] @viewport = [0, 0, @width, @height]
@destroyed = false @destroyed = false
amask = 0xff000000 amask = 0xff000000
rmask = 0x00ff0000 rmask = 0x00ff0000
gmask = 0x0000ff00 gmask = 0x0000ff00
bmask = 0x000000ff bmask = 0x000000ff
#@background ||= Surface.new(SWSURFACE, @width, @height, 32, rmask, gmask, bmask, amask) #@background ||= Surface.new(SWSURFACE, @width, @height, 32, rmask, gmask, bmask, amask)
@contents ||= Surface.new(SWSURFACE, @width, @height, 32, rmask, gmask, bmask, amask) @contents ||= Surface.new(SWSURFACE, @width, @height, 32, rmask, gmask, bmask, amask)
#按Z坐标插入 #按Z坐标插入
unless $scene.windows.each_with_index do |window, index| unless $scene.windows.each_with_index do |window, index|
if window.z > @z if window.z > @z
$scene.windows.insert(index, self) $scene.windows.insert(index, self)
break true break true
end end
end == true end == true
$scene.windows << self $scene.windows << self
end end
end end
def draw_stroked_text(text,x,y,size=1,font=@font,color=@color,color_stroke=@color_stroke) def draw_stroked_text(text,x,y,size=1,font=@font,color=@color,color_stroke=@color_stroke)
[[x-size,y-size], [x-size,y], [x-size,y+size], [[x-size,y-size], [x-size,y], [x-size,y+size],
[x,y-size], [x,y+size], [x,y-size], [x,y+size],
[x+size,y-size], [x+size,y], [x+size,y+size], [x+size,y-size], [x+size,y], [x+size,y+size],
].each{|pos|font.draw_blended_utf8(@contents, text, pos[0], pos[1], *color)} ].each{|pos|font.draw_blended_utf8(@contents, text, pos[0], pos[1], *color)}
font.draw_blended_utf8(@contents, text, x, y, *color_stroke) font.draw_blended_utf8(@contents, text, x, y, *color_stroke)
end end
def include?(x,y) def include?(x,y)
x >= @x && x < @x + @width && y >= @y && y < @y + @height x >= @x && x < @x + @width && y >= @y && y < @y + @height
end end
def destroy def destroy
@destroyed = true @destroyed = true
@contents.destroy if @contents @contents.destroy if @contents
$scene.windows.delete self if $scene $scene.windows.delete self if $scene
end end
def destroyed? def destroyed?
@destroyed @destroyed
end end
def draw(screen) def draw(screen)
return unless self.contents && self.visible? && !self.destroyed? return unless self.contents && self.visible? && !self.destroyed?
Surface.blit(self.contents, *self.viewport, screen, self.x, self.y) Surface.blit(self.contents, *self.viewport, screen, self.x, self.y)
end end
def clear(x=0, y=0, width=@width, height=@height) def clear(x=0, y=0, width=@width, height=@height)
if @background if @background
Surface.blit(@background,x,y,width,height,@contents,x,y) Surface.blit(@background,x,y,width,height,@contents,x,y)
elsif $scene and $scene.background elsif $scene and $scene.background
Surface.blit($scene.background,@x+x,@y+y,width,height,@contents,x,y) Surface.blit($scene.background,@x+x,@y+y,width,height,@contents,x,y)
else else
@contents.fill_rect(x,y,width,height,0xFF000000) @contents.fill_rect(x,y,width,height,0xFF000000)
end end
end end
def update def update
#子类定义 #子类定义
end end
def refresh def refresh
#子类定义 #子类定义
end end
def mousemoved(x,y) def mousemoved(x,y)
#子类定义 #子类定义
end end
def clicked def clicked
#子类定义 #子类定义
end end
def mouseleftbuttonup def mouseleftbuttonup
#子类定义 #子类定义
end end
def lostfocus(active_window=nil) def lostfocus(active_window=nil)
#子类定义 #子类定义
end end
def cursor_up(wrap=false) def cursor_up(wrap=false)
#子类定义 #子类定义
end end
def cursor_down(wrap=false) def cursor_down(wrap=false)
#子类定义 #子类定义
end end
def scroll_up def scroll_up
cursor_up cursor_up
end end
def scroll_down def scroll_down
cursor_down cursor_down
end end
end end
\ No newline at end of file
#============================================================================== #==============================================================================
# ■ Scene_Title # ■ Scene_Title
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
#  title #  title
#============================================================================== #==============================================================================
require_relative 'widget_scrollbar' require_relative 'widget_scrollbar'
require_relative 'widget_inputbox' require_relative 'widget_inputbox'
require_relative 'chatmessage' require_relative 'chatmessage'
require_relative 'window_scrollable' require_relative 'window_scrollable'
class Window_Chat < Window_Scrollable class Window_Chat < Window_Scrollable
WLH=16 WLH=16
def initialize(x, y, width, height) def initialize(x, y, width, height)
super(x,y,width,height) super(x,y,width,height)
if @width > 600 #判断大厅还是房间,这个判据比较囧,待优化 if @width > 600 #判断大厅还是房间,这个判据比较囧,待优化
@chat_background = Surface.load("graphics/system/chat.png").display_format @chat_background = Surface.load("graphics/system/chat.png").display_format
else else
@chat_background = Surface.load("graphics/system/chat_room.png").display_format @chat_background = Surface.load("graphics/system/chat_room.png").display_format
end end
@background = @contents.copy_rect(0,0,@contents.w,@contents.h) #new而已。。 @background = @contents.copy_rect(0,0,@contents.w,@contents.h) #new而已。。
@background.fill_rect(0,0,@background.w, @background.h, 0xFFb2cefe) @background.fill_rect(0,0,@background.w, @background.h, 0xFFb2cefe)
@background.put(@chat_background,0,31-4) @background.put(@chat_background,0,31-4)
@tab = Surface.load "graphics/system/tab.png" @tab = Surface.load "graphics/system/tab.png"
@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
if !@chat_input.value.empty? if !@chat_input.value.empty?
chatmessage = ChatMessage.new($game.user, @chat_input.value, @channel) chatmessage = ChatMessage.new($game.user, @chat_input.value, @channel)
$game.chat chatmessage $game.chat chatmessage
Game_Event.push Game_Event::Chat.new(chatmessage) if $game.show_chat_self Game_Event.push Game_Event::Chat.new(chatmessage) if $game.show_chat_self
true true
end end
end end
end end
@chat_input.refresh @chat_input.refresh
@font = TTF.open("fonts/wqy-microhei.ttc", 14) @font = TTF.open("fonts/wqy-microhei.ttc", 14)
@scrollbar = Widget_ScrollBar.new(self,@x+@width-20-8,@y+31+3,@height-68) @scrollbar = Widget_ScrollBar.new(self,@x+@width-20-8,@y+31+3,@height-68)
@page_size = (@height-68)/WLH @page_size = (@height-68)/WLH
@@list ||= {} @@list ||= {}
@list_splited = {} @list_splited = {}
@@list.each_pair do |channel, chatmessages| @@list.each_pair do |channel, chatmessages|
chatmessages.each do |chatmessage| chatmessages.each do |chatmessage|
add_split(chatmessage) add_split(chatmessage)
end end
end end
@channels = [] @channels = []
self.channel = :lobby self.channel = :lobby
end end
def add(chatmessage) def add(chatmessage)
@@list[chatmessage.channel] ||= [] @@list[chatmessage.channel] ||= []
unless @channels.include? chatmessage.channel unless @channels.include? chatmessage.channel
@channels << chatmessage.channel @channels << chatmessage.channel
refresh refresh
end 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)
if chatmessage.channel == @channel if chatmessage.channel == @channel
@scroll = [@items.size - @page_size, 0].max if scroll_bottom @scroll = [@items.size - @page_size, 0].max if scroll_bottom
refresh refresh
end end
end end
def add_split(chatmessage) def add_split(chatmessage)
@list_splited[chatmessage.channel] ||= [] @list_splited[chatmessage.channel] ||= []
@list_splited[chatmessage.channel] << [chatmessage, ""] @list_splited[chatmessage.channel] << [chatmessage, ""]
width = name_width(chatmessage) width = name_width(chatmessage)
line = 0 line = 0
chatmessage.message.each_char do |char| chatmessage.message.each_char do |char|
if char == "\n" if char == "\n"
line += 1 line += 1
width = 0 width = 0
@list_splited[chatmessage.channel] << [chatmessage.message_color, ""] @list_splited[chatmessage.channel] << [chatmessage.message_color, ""]
else else
char_width = @font.text_size(char)[0] char_width = @font.text_size(char)[0]
if char_width + width > @width-14-20 if char_width + width > @width-14-20
line += 1 line += 1
width = char_width width = char_width
@list_splited[chatmessage.channel] << [chatmessage.message_color, char] @list_splited[chatmessage.channel] << [chatmessage.message_color, char]
else else
@list_splited[chatmessage.channel].last[1] << char @list_splited[chatmessage.channel].last[1] << char
width += char_width width += char_width
end end
end end
end end
end end
def mousemoved(x,y) def mousemoved(x,y)
if y-@y < 31 and (x-@x) < @channels.size * 100 if y-@y < 31 and (x-@x) < @channels.size * 100
self.index = @channels[(x-@x) / 100] self.index = @channels[(x-@x) / 100]
else else
self.index = nil self.index = nil
end end
end end
def clicked def clicked
case @index case @index
when nil when nil
when Integer when Integer
else else
self.channel = @index self.channel = @index
end end
end end
def channel=(channel) def channel=(channel)
return if @channel == channel return if @channel == channel
@channel = channel @channel = channel
@channels << channel unless @channels.include? channel @channels << channel unless @channels.include? channel
@list_splited[channel] ||= [] @list_splited[channel] ||= []
@items = @list_splited[channel] @items = @list_splited[channel]
@scroll = [@items.size - @page_size, 0].max @scroll = [@items.size - @page_size, 0].max
refresh refresh
end end
def draw_item(index, status=0) def draw_item(index, status=0)
case index case index
when nil when nil
when Integer #描绘聊天消息 when Integer #描绘聊天消息
draw_item_chatmessage(index, status) draw_item_chatmessage(index, status)
else #描绘频道标签 else #描绘频道标签
draw_item_channel(index, status) draw_item_channel(index, status)
end end
end end
def draw_item_channel(channel, status) def draw_item_channel(channel, status)
index = @channels.index(channel) index = @channels.index(channel)
Surface.blit(@tab,0,@channel == channel ? 0 : 31,100,31,@contents,index*100+3,0) Surface.blit(@tab,0,@channel == channel ? 0 : 31,100,31,@contents,index*100+3,0)
channel_name = ChatMessage.channel_name channel channel_name = ChatMessage.channel_name channel
x = index*100+(100 - @font.text_size(channel_name)[0])/2 x = index*100+(100 - @font.text_size(channel_name)[0])/2
draw_stroked_text(channel_name,x,8,1,@font, [255,255,255], ChatMessage.channel_color(channel)) draw_stroked_text(channel_name,x,8,1,@font, [255,255,255], ChatMessage.channel_color(channel))
end end
def draw_item_chatmessage(index, status) def draw_item_chatmessage(index, status)
x,y = item_rect_chatmessage(index) x,y = item_rect_chatmessage(index)
chatmessage, message = @items[index] chatmessage, message = @items[index]
if chatmessage.is_a? ChatMessage if chatmessage.is_a? ChatMessage
@font.draw_blended_utf8(@contents, chatmessage.user.name+':', x, y, *chatmessage.name_color) if chatmessage.name_visible? @font.draw_blended_utf8(@contents, chatmessage.user.name+':', x, y, *chatmessage.name_color) if chatmessage.name_visible?
@font.draw_blended_utf8(@contents, message, x+name_width(chatmessage), y, *chatmessage.message_color) unless chatmessage.message.empty? @font.draw_blended_utf8(@contents, message, x+name_width(chatmessage), y, *chatmessage.message_color) unless chatmessage.message.empty?
else else
@font.draw_blended_utf8(@contents, message, x, y, *chatmessage) unless message.empty? @font.draw_blended_utf8(@contents, message, x, y, *chatmessage) unless message.empty?
end end
end end
def item_rect(index) def item_rect(index)
case index case index
when nil when nil
when Integer #描绘聊天消息 when Integer #描绘聊天消息
item_rect_chatmessage(index) item_rect_chatmessage(index)
else #描绘频道标签 else #描绘频道标签
item_rect_channel(index) item_rect_channel(index)
end end
end end
def item_rect_channel(channel) def item_rect_channel(channel)
[@channels.index(channel)*100+3, 0, 100, 31] [@channels.index(channel)*100+3, 0, 100, 31]
end end
def item_rect_chatmessage(index) def item_rect_chatmessage(index)
[8, (index-@scroll)*WLH+31+3, @width, self.class::WLH] [8, (index-@scroll)*WLH+31+3, @width, self.class::WLH]
end end
def refresh def refresh
super super
@channels.each {|channel|draw_item_channel(channel, @index==channel)} @channels.each {|channel|draw_item_channel(channel, @index==channel)}
end end
def name_width(chatmessage) def name_width(chatmessage)
chatmessage.name_visible? ? @font.text_size(chatmessage.user.name+':')[0] : 0 chatmessage.name_visible? ? @font.text_size(chatmessage.user.name+':')[0] : 0
end end
def index_legal?(index) def index_legal?(index)
case index case index
when nil,Integer when nil,Integer
super super
else else
@channels.include? index @channels.include? index
end end
end end
def scroll_up def scroll_up
self.scroll -= 1 self.scroll -= 1
end end
def scroll_down def scroll_down
self.scroll += 1 self.scroll += 1
end end
def update def update
@chat_input.update @chat_input.update
end end
end end
\ No newline at end of file
class Window_Config < Window class Window_Config < Window
def initialize(x,y) def initialize(x,y)
super(x,y,$screen.w, $screen.h) super(x,y,$screen.w, $screen.h)
@checkbox = Surface.load('graphics/system/checkbox.png') @checkbox = Surface.load('graphics/system/checkbox.png')
@button = Surface.load('graphics/system/button.png') @button = Surface.load('graphics/system/button.png')
@background = Surface.load('graphics/config/background.png').display_format @background = Surface.load('graphics/config/background.png').display_format
@contents = Surface.load('graphics/config/background.png').display_format @contents = Surface.load('graphics/config/background.png').display_format
@font = TTF.open('fonts/wqy-microhei.ttc', 20) @font = TTF.open('fonts/wqy-microhei.ttc', 20)
@index = nil @index = nil
@items = { @items = {
:fullscreen => [200,160,120,WLH], :fullscreen => [200,160,120,WLH],
:bgm => [200,160+WLH,120,WLH], :bgm => [200,160+WLH,120,WLH],
:avatar_cache => [200+220, 160+WLH*2,@button.w/3, @button.h], :avatar_cache => [200+220, 160+WLH*2,@button.w/3, @button.h],
:return => [200,160+WLH*3+10,100,WLH] :return => [200,160+WLH*3+10,100,WLH]
} }
refresh refresh
end end
def draw_item(index, status=0) def draw_item(index, status=0)
case index case index
when :fullscreen when :fullscreen
Surface.blit(@checkbox, 20*status, $config['screen']['fullscreen'] ? 20 : 0, 20, 20, @contents, @items[:fullscreen][0],@items[:fullscreen][1]) Surface.blit(@checkbox, 20*status, $config['screen']['fullscreen'] ? 20 : 0, 20, 20, @contents, @items[:fullscreen][0],@items[:fullscreen][1])
case status case status
when 0 when 0
@font.draw_blended_utf8(@contents, "全屏模式", @items[:fullscreen][0]+24, @items[:fullscreen][1], 0xFF,0xFF,0xFF) @font.draw_blended_utf8(@contents, "全屏模式", @items[:fullscreen][0]+24, @items[:fullscreen][1], 0xFF,0xFF,0xFF)
when 1 when 1
@font.draw_shaded_utf8(@contents, "全屏模式", @items[:fullscreen][0]+24, @items[:fullscreen][1], 0xFF,0xFF,0xFF, 0x11, 0x11, 0x11) @font.draw_shaded_utf8(@contents, "全屏模式", @items[:fullscreen][0]+24, @items[:fullscreen][1], 0xFF,0xFF,0xFF, 0x11, 0x11, 0x11)
when 2 when 2
@font.draw_shaded_utf8(@contents, "全屏模式", @items[:fullscreen][0]+24, @items[:fullscreen][1], 0x11,0x11,0x11, 0xFF, 0xFF, 0xFF) @font.draw_shaded_utf8(@contents, "全屏模式", @items[:fullscreen][0]+24, @items[:fullscreen][1], 0x11,0x11,0x11, 0xFF, 0xFF, 0xFF)
end end
when :bgm when :bgm
Surface.blit(@checkbox, 20*status, $config['bgm'] ? 20 : 0, 20, 20, @contents, @items[:bgm][0], @items[:bgm][1]) Surface.blit(@checkbox, 20*status, $config['bgm'] ? 20 : 0, 20, 20, @contents, @items[:bgm][0], @items[:bgm][1])
case status case status
when 0 when 0
@font.draw_blended_utf8(@contents, "BGM", @items[:bgm][0]+24, @items[:bgm][1], 0xFF,0xFF,0xFF) @font.draw_blended_utf8(@contents, "BGM", @items[:bgm][0]+24, @items[:bgm][1], 0xFF,0xFF,0xFF)
when 1 when 1
@font.draw_shaded_utf8(@contents, "BGM", @items[:bgm][0]+24, @items[:bgm][1], 0xFF,0xFF,0xFF, 0x11, 0x11, 0x11) @font.draw_shaded_utf8(@contents, "BGM", @items[:bgm][0]+24, @items[:bgm][1], 0xFF,0xFF,0xFF, 0x11, 0x11, 0x11)
when 2 when 2
@font.draw_shaded_utf8(@contents, "BGM", @items[:bgm][0]+24, @items[:bgm][1], 0x11,0x11,0x11, 0xFF, 0xFF, 0xFF) @font.draw_shaded_utf8(@contents, "BGM", @items[:bgm][0]+24, @items[:bgm][1], 0x11,0x11,0x11, 0xFF, 0xFF, 0xFF)
end end
when :avatar_cache when :avatar_cache
size = 0 size = 0
count = 0 count = 0
Dir.glob("graphics/avatars/*_*.png") do |file| Dir.glob("graphics/avatars/*_*.png") do |file|
count += 1 count += 1
size += File.size(file) size += File.size(file)
end end
@font.draw_blended_utf8(@contents, "头像缓存: #{count}个文件, #{filesize_inspect(size)}", 200, @items[:avatar_cache][1], 0xFF,0xFF,0xFF) @font.draw_blended_utf8(@contents, "头像缓存: #{count}个文件, #{filesize_inspect(size)}", 200, @items[:avatar_cache][1], 0xFF,0xFF,0xFF)
Surface.blit(@button, @button.w/3*status, 0, @button.w/3, @button.h, @contents, @items[:avatar_cache][0],@items[:avatar_cache][1]) Surface.blit(@button, @button.w/3*status, 0, @button.w/3, @button.h, @contents, @items[:avatar_cache][0],@items[:avatar_cache][1])
@font.draw_blended_utf8(@contents, "清空", @items[:avatar_cache][0]+10, @items[:avatar_cache][1]+5, 0xFF,0xFF,0xFF) @font.draw_blended_utf8(@contents, "清空", @items[:avatar_cache][0]+10, @items[:avatar_cache][1]+5, 0xFF,0xFF,0xFF)
when :return when :return
@font.draw_blended_utf8(@contents, "回到标题画面", @items[:return][0],@items[:return][1], 0xFF,0xFF,0xFF) @font.draw_blended_utf8(@contents, "回到标题画面", @items[:return][0],@items[:return][1], 0xFF,0xFF,0xFF)
end end
end end
def item_rect(index) def item_rect(index)
@items[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
@index = nil @index = nil
else else
@index = index @index = index
clear(*item_rect(@index)) clear(*item_rect(@index))
draw_item(@index, 1) draw_item(@index, 1)
end end
end end
def mousemoved(x,y) def mousemoved(x,y)
self.index = @items.each do |index, item_rect| self.index = @items.each do |index, item_rect|
if x.between?(@x+item_rect[0], @x+item_rect[0]+item_rect[2]) and y.between?(@y+item_rect[1], @y+item_rect[1]+item_rect[3]) if x.between?(@x+item_rect[0], @x+item_rect[0]+item_rect[2]) and y.between?(@y+item_rect[1], @y+item_rect[1]+item_rect[3])
break index break index
end end
end end
end end
def refresh def refresh
clear clear
@items.each_key{|index|draw_item(index)} @items.each_key{|index|draw_item(index)}
end end
def clicked def clicked
case @index case @index
when :fullscreen when :fullscreen
clear(*item_rect(@index)) clear(*item_rect(@index))
$config['screen']['fullscreen'] = !$config['screen']['fullscreen'] $config['screen']['fullscreen'] = !$config['screen']['fullscreen']
$screen.destroy $screen.destroy
style = HWSURFACE style = HWSURFACE
style |= FULLSCREEN if $config['screen']["fullscreen"] style |= FULLSCREEN if $config['screen']["fullscreen"]
$screen = Screen.open($config['screen']["width"], $config['screen']["height"], 0, style) $screen = Screen.open($config['screen']["width"], $config['screen']["height"], 0, style)
draw_item(@index, 1) draw_item(@index, 1)
when :bgm when :bgm
clear(*item_rect(@index)) clear(*item_rect(@index))
$config['bgm'] = !$config['bgm'] $config['bgm'] = !$config['bgm']
if $config['bgm'] if $config['bgm']
$scene = Scene_Config.new $scene = Scene_Config.new
else else
$scene.last_bgm = nil $scene.last_bgm = nil
Mixer.fade_out_music(800) if SDL.inited_system(INIT_AUDIO) != 0 Mixer.fade_out_music(800) if SDL.inited_system(INIT_AUDIO) != 0
end end
draw_item(@index, 1) draw_item(@index, 1)
when :avatar_cache when :avatar_cache
#clear(*item_rect(@index)) #clear(*item_rect(@index))
Dir.glob("graphics/avatars/*_*.png") do |file| Dir.glob("graphics/avatars/*_*.png") do |file|
File.delete file File.delete file
end end
refresh refresh
#draw_item(:avatar_cache,1) #draw_item(:avatar_cache,1)
when :return when :return
$scene = Scene_Title.new $scene = Scene_Title.new
end end
Config.save Config.save
end end
def filesize_inspect(size) def filesize_inspect(size)
case size case size
when 0...1024 when 0...1024
size.to_s + "B" size.to_s + "B"
when 1024...1024*1024 when 1024...1024*1024
(size/1024).to_s + "KB" (size/1024).to_s + "KB"
else else
(size/1024/1024).to_s + "MB" (size/1024/1024).to_s + "MB"
end end
end end
end end
\ No newline at end of file
class Window_Deck < Window class Window_Deck < Window
attr_reader :index attr_reader :index
def initialize def initialize
@items = Dir.glob("ygocore/deck/*.ydk")[0, 10] @items = Dir.glob("ygocore/deck/*.ydk")[0, 10]
p @items p @items
@background = Surface.load(@items.size > 4 ? 'graphics/lobby/host.png' : 'graphics/system/msgbox.png').display_format @background = Surface.load(@items.size > 4 ? 'graphics/lobby/host.png' : 'graphics/system/msgbox.png').display_format
super((1024-@background.w)/2, 230, @background.w, @background.h, 300) super((1024-@background.w)/2, 230, @background.w, @background.h, 300)
@items_button = Surface.load("graphics/system/deck_buttons.png") @items_button = Surface.load("graphics/system/deck_buttons.png")
@items_buttons = {edit: "编辑", delete: "删除", export: "导出"} @items_buttons = {edit: "编辑", delete: "删除", export: "导出"}
button_y = @height - 36 button_y = @height - 36
@button = Surface.load("graphics/system/button.png") @button = Surface.load("graphics/system/button.png")
@buttons = {import: "导入", edit: "编辑", close: "关闭"} @buttons = {import: "导入", edit: "编辑", close: "关闭"}
space = (@width - @buttons.size * @button.w / 3) / (@buttons.size + 1) space = (@width - @buttons.size * @button.w / 3) / (@buttons.size + 1)
@buttons_pos = {} @buttons_pos = {}
@buttons.each_with_index do |button, index| @buttons.each_with_index do |button, index|
@buttons_pos[button[0]] = [(space+@button.w/3)*index+space, button_y, @button.w/3, @button.h] @buttons_pos[button[0]] = [(space+@button.w/3)*index+space, button_y, @button.w/3, @button.h]
end end
@font = TTF.open("fonts/wqy-microhei.ttc", 16) @font = TTF.open("fonts/wqy-microhei.ttc", 16)
@title_color = [0xFF, 0xFF, 0xFF] @title_color = [0xFF, 0xFF, 0xFF]
@color = [0x04, 0x47, 0x7c] @color = [0x04, 0x47, 0x7c]
refresh refresh
end end
def refresh def refresh
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)
@items = Dir.glob("ygocore/deck/*.ydk")[0, 10] @items = Dir.glob("ygocore/deck/*.ydk")[0, 10]
@background = Surface.load(@items.size > 4 ? 'graphics/lobby/host.png' : 'graphics/system/msgbox.png').display_format @background = Surface.load(@items.size > 4 ? 'graphics/lobby/host.png' : 'graphics/system/msgbox.png').display_format
@height = @background.h @height = @background.h
@items.each_with_index do |deck, index| @items.each_with_index do |deck, index|
@font.draw_blended_utf8(@contents, File.basename(deck, ".ydk"), 16, 28+WLH*index, *@color) @font.draw_blended_utf8(@contents, File.basename(deck, ".ydk"), 16, 28+WLH*index, *@color)
end end
@items.size.times do |index| @items.size.times do |index|
@items_buttons.each_key do |key| @items_buttons.each_key do |key|
draw_item([index, key], self.index==[index, key] ? 1 : 0) draw_item([index, key], self.index==[index, key] ? 1 : 0)
end end
end end
@buttons.each_key do |index| @buttons.each_key do |index|
draw_item(index, self.index==index ? 1 : 0) draw_item(index, self.index==index ? 1 : 0)
end end
end end
def draw_item(index, status=0) def draw_item(index, status=0)
x, y=item_rect(index) x, y=item_rect(index)
if index.is_a? Array if index.is_a? Array
Surface.blit(@items_button, status*@items_button.w/3, @items_buttons.keys.index(index[1])*@items_button.h/3, @items_button.w/3, @items_button.h/3, @contents, x, y) Surface.blit(@items_button, status*@items_button.w/3, @items_buttons.keys.index(index[1])*@items_button.h/3, @items_button.w/3, @items_button.h/3, @contents, x, y)
else else
Surface.blit(@button, @button.w/3*status, 0, @button.w/3, @button.h, @contents, x, y) Surface.blit(@button, @button.w/3*status, 0, @button.w/3, @button.h, @contents, x, y)
text_size = @font.text_size(@buttons[index]) text_size = @font.text_size(@buttons[index])
@font.draw_blended_utf8(@contents, @buttons[index], x+(@button.w/3-text_size[0])/2, y+(@button.h-text_size[1])/2, 0xFF, 0xFF, 0xFF) @font.draw_blended_utf8(@contents, @buttons[index], x+(@button.w/3-text_size[0])/2, y+(@button.h-text_size[1])/2, 0xFF, 0xFF, 0xFF)
end end
end end
def mousemoved(x, y) def mousemoved(x, y)
new_index = nil new_index = nil
line = (y-@y-28)/WLH line = (y-@y-28)/WLH
if line.between?(0, @items.size-1) if line.between?(0, @items.size-1)
i = (x - @x - (@width - @items_buttons.size * @items_button.w / 3)) / (@items_button.w/3) i = (x - @x - (@width - @items_buttons.size * @items_button.w / 3)) / (@items_button.w/3)
if i >= 0 if i >= 0
new_index = [line, @items_buttons.keys[i]] new_index = [line, @items_buttons.keys[i]]
else else
new_index = [line, :edit] new_index = [line, :edit]
end end
else else
@buttons_pos.each_key do |index| @buttons_pos.each_key do |index|
if (x - @x).between?(@buttons_pos[index][0], @buttons_pos[index][0]+@buttons_pos[index][2]) and (y-@y).between?(@buttons_pos[index][1], @buttons_pos[index][1]+@buttons_pos[index][3]) if (x - @x).between?(@buttons_pos[index][0], @buttons_pos[index][0]+@buttons_pos[index][2]) and (y-@y).between?(@buttons_pos[index][1], @buttons_pos[index][1]+@buttons_pos[index][3])
new_index = index new_index = index
break break
end end
end end
end end
self.index = new_index self.index = new_index
end end
def item_rect(index) def item_rect(index)
if index.is_a? Array if index.is_a? Array
[ [
@width - (@items_button.w/3) * (@items_buttons.keys.reverse.index(index[1])+1), @width - (@items_button.w/3) * (@items_buttons.keys.reverse.index(index[1])+1),
28+WLH*index[0], 28+WLH*index[0],
@items_button.w/3, @items_button.w/3,
@items_button.h/3 @items_button.h/3
] ]
else else
@buttons_pos[index] @buttons_pos[index]
end end
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
@index = index @index = index
if @index if @index
clear(*item_rect(@index)) clear(*item_rect(@index))
draw_item(@index, 1) draw_item(@index, 1)
end end
end end
def clicked def clicked
case self.index case self.index
when :import when :import
import import
refresh refresh
when :edit when :edit
Ygocore.run_ygocore(:deck) Ygocore.run_ygocore(:deck)
when :close when :close
destroy destroy
when Array when Array
case index[1] case index[1]
when :edit when :edit
Ygocore.run_ygocore(File.basename(@items[index[0]], ".ydk")) Ygocore.run_ygocore(File.basename(@items[index[0]], ".ydk"))
when :delete when :delete
require_relative 'widget_msgbox' require_relative 'widget_msgbox'
Widget_Msgbox.new("删除卡组", "确定要删除卡组 #{File.basename(@items[index[0]], '.ydk')} 吗", buttons={ok: "确定", cancel: "取消"}) do |clicked| Widget_Msgbox.new("删除卡组", "确定要删除卡组 #{File.basename(@items[index[0]], '.ydk')} 吗", buttons={ok: "确定", cancel: "取消"}) do |clicked|
if clicked == :ok if clicked == :ok
File.delete @items[index[0]] File.delete @items[index[0]]
refresh refresh
end end
end end
when :export when :export
export export
end end
end end
end end
def import def import
file = Dialog.get_open_file("导入卡组", "所有支持的卡组 (*.ydk;*.txt;*.deck)" => "*.ydk;*.txt;*.deck", "ygocore卡组 (*.ydk)" => "*.ydk", "OcgSoft卡组 (*.txt;*.deck)" => "*.txt;*.deck") file = Dialog.get_open_file("导入卡组", "所有支持的卡组 (*.ydk;*.txt;*.deck)" => "*.ydk;*.txt;*.deck", "ygocore卡组 (*.ydk)" => "*.ydk", "OcgSoft卡组 (*.txt;*.deck)" => "*.txt;*.deck")
if !file.empty? if !file.empty?
#fix for stdlib File.extname #fix for stdlib File.extname
file =~ /(\.deck|\.txt|\.ydk)$/i file =~ /(\.deck|\.txt|\.ydk)$/i
extname = $1 extname = $1
Dir.mkdir "ygocore/deck" unless File.directory?("ygocore/deck") Dir.mkdir "ygocore/deck" unless File.directory?("ygocore/deck")
open("ygocore/deck/#{File.basename(file, extname)+".ydk"}", 'w') do |dest| open("ygocore/deck/#{File.basename(file, extname)+".ydk"}", 'w') do |dest|
if file =~ /(\.deck|\.txt)$/i if file =~ /(\.deck|\.txt)$/i
deck = Deck.load(file) deck = Deck.load(file)
dest.puts("#main") dest.puts("#main")
deck.main.each { |card| dest.puts card.number } deck.main.each { |card| dest.puts card.number }
dest.puts("#extra") dest.puts("#extra")
deck.extra.each { |card| dest.puts card.number } deck.extra.each { |card| dest.puts card.number }
dest.puts("!side") dest.puts("!side")
deck.side.each { |card| dest.puts card.number } deck.side.each { |card| dest.puts card.number }
else else
open(file) do |src| open(file) do |src|
dest.write src.read dest.write src.read
end end
end end
end rescue ($log.error($!.inspect) { $!.backtrace.inspect }; Widget_Msgbox.new("导入卡组", "导入卡组失败", :ok => "确定")) end rescue ($log.error($!.inspect) { $!.backtrace.inspect }; Widget_Msgbox.new("导入卡组", "导入卡组失败", :ok => "确定"))
end end
end end
def export def export
require_relative 'dialog' require_relative 'dialog'
file = Dialog.get_open_file("导出卡组", {"ygocore卡组 (*.ydk)" => "*.ydk", "OcgSoft卡组 (*.txt)" => "*.txt"}, [".ydk", ".txt"]) file = Dialog.get_open_file("导出卡组", {"ygocore卡组 (*.ydk)" => "*.ydk", "OcgSoft卡组 (*.txt)" => "*.txt"}, [".ydk", ".txt"])
if !file.empty? if !file.empty?
@items[index[0]] @items[index[0]]
open(@items[index[0]]) do |src| open(@items[index[0]]) do |src|
if file =~ /.txt$/i if file =~ /.txt$/i
main = [] main = []
extra = [] extra = []
side = [] side = []
now_side = false now_side = false
src.readlines.each do |line| src.readlines.each do |line|
line.chomp! line.chomp!
if line[0, 1] == "#" if line[0, 1] == "#"
next next
elsif line[0, 5] == "!side" elsif line[0, 5] == "!side"
now_side = true now_side = true
else else
card = Card.find("number = '#{line.rjust(8, '0')}'")[0] card = Card.find("number = '#{line.rjust(8, '0')}'")[0]
next if card.nil? next if card.nil?
if now_side if now_side
side << card side << card
elsif card.extra? elsif card.extra?
extra << card extra << card
else else
main << card main << card
end end
end end
end end
open(file, 'w:GBK') do |dest| open(file, 'w:GBK') do |dest|
main.each { |card| dest.puts "[#{card.name}]##" } main.each { |card| dest.puts "[#{card.name}]##" }
dest.puts "####" dest.puts "####"
side.each { |card| dest.puts "[#{card.name}]##" } side.each { |card| dest.puts "[#{card.name}]##" }
dest.puts "====" dest.puts "===="
extra.each { |card| dest.puts "[#{card.name}]##" } extra.each { |card| dest.puts "[#{card.name}]##" }
end end
else else
open(file, 'w') do |dest| open(file, 'w') do |dest|
dest.write src.read dest.write src.read
end end
end end
end end
end end
end end
end end
\ No newline at end of file
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)
@items = ["常见问题", "卡组编辑", "建立房间"] @items = ["常见问题", "卡组编辑", "建立房间"]
@button = Surface.load("graphics/lobby/button.png") @button = Surface.load("graphics/lobby/button.png")
super(x, y, @items.size*@button.w/3+@items.size*4, 30) super(x, y, @items.size*@button.w/3+@items.size*4, 30)
@font = TTF.open("fonts/wqy-microhei.ttc", 15) @font = TTF.open("fonts/wqy-microhei.ttc", 15)
refresh refresh
end end
def draw_item(index, status=0) def draw_item(index, status=0)
x, y=item_rect(index) x, y=item_rect(index)
Surface.blit(@button, status*@button.w/3, 0, @button.w/3, @button.h, @contents, x, y) 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]) draw_stroked_text(@items[index], x+8, y+3, 2, @font, [0xdf, 0xf1, 0xff], [0x27, 0x43, 0x59])
end end
def item_rect(index) def item_rect(index)
[index*@button.w/3+(index)*4, 0, @button.w/3, @height] [index*@button.w/3+(index)*4, 0, @button.w/3, @height]
end end
def mousemoved(x, y) def mousemoved(x, y)
if (x-@x) % (@button.w/3+4) >= @button.w/3 if (x-@x) % (@button.w/3+4) >= @button.w/3
self.index = nil self.index = nil
else else
self.index = (x-@x)/(@button.w/3+4) self.index = (x-@x)/(@button.w/3+4)
end 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
case @index case @index
when 0 #常见问题 when 0 #常见问题
require_relative 'dialog' require_relative 'dialog'
Dialog.web "http://my-card.in/login?user[name]=#{CGI.escape $game.user.name}&user[password]=#{CGI.escape $game.password}&continue=/topics/1453" Dialog.web "http://my-card.in/login?user[name]=#{CGI.escape $game.user.name}&user[password]=#{CGI.escape $game.password}&continue=/topics/1453"
when 1 #卡组编辑 when 1 #卡组编辑
require_relative 'deck' require_relative 'deck'
$game.class.deck_edit $game.class.deck_edit
when 2 #建立房间 when 2 #建立房间
@host_window = Window_Host.new(300, 200) @host_window = Window_Host.new(300, 200)
end 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?
end end
end end
#encoding: UTF-8 #encoding: UTF-8
#============================================================================== #==============================================================================
# ■ Window_Roomitems # ■ Window_Roomitems
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
#  大厅内房间列表 #  大厅内房间列表
#============================================================================== #==============================================================================
require_relative 'window_scrollable' require_relative 'window_scrollable'
require_relative 'window_join' require_relative 'window_join'
class Window_RoomList < Window_Scrollable class Window_RoomList < Window_Scrollable
attr_reader :items attr_reader :items
WLH = 48 WLH = 48
def initialize(x, y, items) def initialize(x, y, items)
@button = Surface.load('graphics/lobby/room.png') @button = Surface.load('graphics/lobby/room.png')
@button.set_alpha(RLEACCEL, 255) @button.set_alpha(RLEACCEL, 255)
#@background = Surface.load 'graphics/lobby/roomitems.png' #@background = Surface.load 'graphics/lobby/roomitems.png'
#@contents = Surface.load 'graphics/lobby/roomitems.png' #@contents = Surface.load 'graphics/lobby/roomitems.png'
super(x,y,@button.w / 3, ($config['screen']['height'] - 288) / 48 * 48) super(x,y,@button.w / 3, ($config['screen']['height'] - 288) / 48 * 48)
@item_max = 0 @item_max = 0
@font = TTF.open("fonts/wqy-microhei.ttc", 16) @font = TTF.open("fonts/wqy-microhei.ttc", 16)
@color = [0x03, 0x11, 0x22] @color = [0x03, 0x11, 0x22]
@scrollbar = Widget_ScrollBar.new(self,@x+@width,@y,@height) @scrollbar = Widget_ScrollBar.new(self,@x+@width,@y,@height)
self.items = items self.items = items
end end
def draw_item(index, status=0) def draw_item(index, status=0)
y = item_rect(index)[1] y = item_rect(index)[1]
room = @items[index] room = @items[index]
Surface.blit(@button, @width*status, room.full? ? WLH : 0, @width, WLH, @contents, 0, y) Surface.blit(@button, @width*status, room.full? ? WLH : 0, @width, WLH, @contents, 0, y)
@font.draw_blended_utf8(@contents, room.id.to_s, 24, y+8, *@color) @font.draw_blended_utf8(@contents, room.id.to_s, 24, y+8, *@color)
@font.draw_blended_utf8(@contents, room.full? ? "【决斗中】" : room.private? ? "【私密房】" : "【等待中】", 8, y+24, *@color) @font.draw_blended_utf8(@contents, room.full? ? "【决斗中】" : room.private? ? "【私密房】" : "【等待中】", 8, y+24, *@color)
@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 and !room.player1.name.empty? @font.draw_blended_utf8(@contents, room.player1.name, 128, y+24, *room.player1.color) if room.player1 and !room.player1.name.empty?
@font.draw_blended_utf8(@contents, room.player2.name, 320, y+24, *room.player2.color) if room.player2 and !room.player2.name.empty? @font.draw_blended_utf8(@contents, room.player2.name, 320, y+24, *room.player2.color) if room.player2 and !room.player2.name.empty?
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)
end end
end end
def update def update
@join_window.update if @join_window and !@join_window.destroyed? @join_window.update if @join_window and !@join_window.destroyed?
end end
def mousemoved(x,y) def mousemoved(x,y)
return unless self.include?(x,y) return unless self.include?(x,y)
self.index = (y - @y) / WLH + @scroll self.index = (y - @y) / WLH + @scroll
end end
def clicked def clicked
return unless @index and room = @items[@index] return unless @index and room = @items[@index]
if room.full? if room.full?
@joinroom_msgbox = Widget_Msgbox.new("加入房间", "正在加入观战") @joinroom_msgbox = Widget_Msgbox.new("加入房间", "正在加入观战")
$game.watch room $game.watch room
else else
if room.private if room.private
@join_window = Window_Join.new(0,0,room) @join_window = Window_Join.new(0,0,room)
else else
@joinroom_msgbox = Widget_Msgbox.new("加入房间", "正在加入房间") @joinroom_msgbox = Widget_Msgbox.new("加入房间", "正在加入房间")
$game.join room $game.join room
end end
end end
end end
end end
\ No newline at end of file
require_relative 'window_list' require_relative 'window_list'
class Window_Title < Window_List class Window_Title < Window_List
Button_Count = 5 Button_Count = 5
WLH = 50 WLH = 50
attr_reader :x, :y, :width, :height, :single_height, :index attr_reader :x, :y, :width, :height, :single_height, :index
def initialize(x,y) def initialize(x,y)
@button = Surface.load("graphics/system/titlebuttons.png") @button = Surface.load("graphics/system/titlebuttons.png")
@button.set_alpha(RLEACCEL,255) @button.set_alpha(RLEACCEL,255)
@single_height = @button.h / Button_Count @single_height = @button.h / Button_Count
super(x,y,@button.w / 3,WLH * Button_Count - (WLH - @button.h / Button_Count)) super(x,y,@button.w / 3,WLH * Button_Count - (WLH - @button.h / Button_Count))
@cursor_se = Mixer::Wave.load 'audio/se/cursor.ogg' if SDL.inited_system(INIT_AUDIO) != 0 @cursor_se = Mixer::Wave.load 'audio/se/cursor.ogg' if SDL.inited_system(INIT_AUDIO) != 0
self.items = [:决斗开始, :单人模式, :卡组编成, :选项设置, :退出游戏] self.items = [:决斗开始, :单人模式, :卡组编成, :选项设置, :退出游戏]
end end
def index=(index) def index=(index)
if index and @index != index if index and @index != index
Mixer.play_channel(-1,@cursor_se,0) if SDL.inited_system(INIT_AUDIO) != 0 Mixer.play_channel(-1,@cursor_se,0) if SDL.inited_system(INIT_AUDIO) != 0
end end
super super
end end
def mousemoved(x,y) def mousemoved(x,y)
self.index = (y - @y) / WLH self.index = (y - @y) / WLH
end end
def draw_item(index, status=0) def draw_item(index, status=0)
Surface.blit(@button, @width*status, @single_height*index, @width, @single_height, @contents, 0, WLH*index) Surface.blit(@button, @width*status, @single_height*index, @width, @single_height, @contents, 0, WLH*index)
end end
def clicked def clicked
$scene.determine if $scene.is_a? Scene_Title $scene.determine if $scene.is_a? Scene_Title
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, 0x00000000) @contents.fill_rect(x,y,width, height, 0x00000000)
end end
end end
\ No newline at end of file
#encoding: UTF-8 #encoding: UTF-8
#============================================================================== #==============================================================================
# Window_UserInfo # Window_UserInfo
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
# 游戏大厅显示用户信息的类 # 游戏大厅显示用户信息的类
#============================================================================== #==============================================================================
class Window_UserInfo < Window class Window_UserInfo < Window
def initialize(x, y, user) def initialize(x, y, user)
@avatar_boarder = Surface.load("graphics/lobby/avatar_boader.png") @avatar_boarder = Surface.load("graphics/lobby/avatar_boader.png")
super(x,y,280,144) super(x,y,280,144)
@font = TTF.open('fonts/wqy-microhei.ttc', 16) @font = TTF.open('fonts/wqy-microhei.ttc', 16)
@user = user @user = user
@background = Surface.load("graphics/lobby/userinfo.png").display_format @background = Surface.load("graphics/lobby/userinfo.png").display_format
refresh refresh
end end
def refresh def refresh
@contents.put(@background, 0, 0) @contents.put(@background, 0, 0)
@thread = @user.avatar(:middle) do |avatar| @thread = @user.avatar(:middle) do |avatar|
clear(0,0,@avatar_boarder.w, @avatar_boarder.h) clear(0,0,@avatar_boarder.w, @avatar_boarder.h)
@contents.put(avatar, 12, 12) @contents.put(avatar, 12, 12)
@contents.put(@avatar_boarder, 0, 0) @contents.put(@avatar_boarder, 0, 0)
end end
@font.draw_blended_utf8(@contents, @user.name, 160, 12, 0x00,0x00,0x00) unless @user.name.empty? @font.draw_blended_utf8(@contents, @user.name, 160, 12, 0x00,0x00,0x00) unless @user.name.empty?
@font.draw_blended_utf8(@contents, "id: #{@user.id}" , 160, 12+16*2, 0x00,0x00,0x00) @font.draw_blended_utf8(@contents, "id: #{@user.id}" , 160, 12+16*2, 0x00,0x00,0x00)
@font.draw_blended_utf8(@contents, "Lv: #{@user.level}" , 160, 12+16*3, 0x00,0x00,0x00) if @user.respond_to? :level and @user.level #TODO:规范化,level是iduel专属的,但是又不太想让iduel来重定义这个window @font.draw_blended_utf8(@contents, "Lv: #{@user.level}" , 160, 12+16*3, 0x00,0x00,0x00) if @user.respond_to? :level and @user.level #TODO:规范化,level是iduel专属的,但是又不太想让iduel来重定义这个window
@font.draw_blended_utf8(@contents, "经验: #{@user.exp}", 160, 12+16*4, 0x00,0x00,0x00) if @user.respond_to? :exp and @user.exp @font.draw_blended_utf8(@contents, "经验: #{@user.exp}", 160, 12+16*4, 0x00,0x00,0x00) if @user.respond_to? :exp and @user.exp
end end
def dispose def dispose
@thread.exit @thread.exit
super super
end end
end end
#encoding: UTF-8 #encoding: UTF-8
load 'lib/ygocore/window_login.rb' load 'lib/ygocore/window_login.rb'
require 'eventmachine' require 'eventmachine'
require 'open-uri' require 'open-uri'
require 'yaml' require 'yaml'
class Ygocore < Game class Ygocore < Game
attr_reader :username attr_reader :username
attr_accessor :password attr_accessor :password
@@config = YAML.load_file("lib/ygocore/server.yml") @@config = YAML.load_file("lib/ygocore/server.yml")
def initialize def initialize
super super
load 'lib/ygocore/event.rb' load 'lib/ygocore/event.rb'
load 'lib/ygocore/user.rb' load 'lib/ygocore/user.rb'
load 'lib/ygocore/room.rb' load 'lib/ygocore/room.rb'
load 'lib/ygocore/scene_lobby.rb' load 'lib/ygocore/scene_lobby.rb'
require 'json' require 'json'
require 'xmpp4r/client' require 'xmpp4r/client'
require 'xmpp4r/muc' require 'xmpp4r/muc'
end end
def refresh_interval def refresh_interval
60 60
end end
def login(username, password) def login(username, password)
@username = username @username = username
@password = password @password = password
@nickname_conflict = [] @nickname_conflict = []
@@im = Jabber::Client.new(Jabber::JID::new(@username, 'my-card.in', 'mycard')) @@im = Jabber::Client.new(Jabber::JID::new(@username, 'my-card.in', 'mycard'))
@@im_room = Jabber::MUC::MUCClient.new(@@im) @@im_room = Jabber::MUC::MUCClient.new(@@im)
#Jabber.debug = true #Jabber.debug = true
@@im.on_exception do |exception, c, where| @@im.on_exception do |exception, c, where|
$log.error('聊天出错') { [exception, c, where] } $log.error('聊天出错') { [exception, c, where] }
if where == :close if where == :close
Game_Event.push(Game_Event::Chat.new(ChatMessage.new(User.new(:system, 'System'), '聊天连接断开, 可能是网络问题或帐号从其他地点登录'))) Game_Event.push(Game_Event::Chat.new(ChatMessage.new(User.new(:system, 'System'), '聊天连接断开, 可能是网络问题或帐号从其他地点登录')))
else else
Game_Event.push(Game_Event::Chat.new(ChatMessage.new(User.new(:system, 'System'), '聊天连接断开, 5秒后重新连接'))) Game_Event.push(Game_Event::Chat.new(ChatMessage.new(User.new(:system, 'System'), '聊天连接断开, 5秒后重新连接')))
sleep 5 sleep 5
im_connect im_connect
end end
end end
@@im_room.add_message_callback do |m| @@im_room.add_message_callback do |m|
user = m.from.resource == nickname ? @user : User.new(m.from.resource.to_sym, m.from.resource) user = m.from.resource == nickname ? @user : User.new(m.from.resource.to_sym, m.from.resource)
Game_Event.push Game_Event::Chat.new ChatMessage.new(user, m.body, :lobby) rescue $log.error('收到聊天消息') { $! } Game_Event.push Game_Event::Chat.new ChatMessage.new(user, m.body, :lobby) rescue $log.error('收到聊天消息') { $! }
end end
@@im_room.add_private_message_callback do |m| @@im_room.add_private_message_callback do |m|
if m.body #忽略无消息的正在输入等内容 if m.body #忽略无消息的正在输入等内容
user = m.from.resource == nickname ? @user : User.new(m.from.resource.to_sym, m.from.resource) user = m.from.resource == nickname ? @user : User.new(m.from.resource.to_sym, m.from.resource)
Game_Event.push Game_Event::Chat.new ChatMessage.new(user, m.body, user) rescue $log.error('收到私聊消息') { $! } Game_Event.push Game_Event::Chat.new ChatMessage.new(user, m.body, user) rescue $log.error('收到私聊消息') { $! }
end end
end end
@@im_room.add_join_callback do |m| @@im_room.add_join_callback do |m|
Game_Event.push Game_Event::NewUser.new User.new m.from.resource.to_sym, m.from.resource Game_Event.push Game_Event::NewUser.new User.new m.from.resource.to_sym, m.from.resource
end end
@@im_room.add_leave_callback do |m| @@im_room.add_leave_callback do |m|
Game_Event.push Game_Event::MissingUser.new User.new m.from.resource.to_sym, m.from.resource Game_Event.push Game_Event::MissingUser.new User.new m.from.resource.to_sym, m.from.resource
end end
connect connect
im_connect im_connect
end end
def nickname def nickname
return @nickname if @nickname return @nickname if @nickname
if @nickname_conflict.include? @username if @nickname_conflict.include? @username
1.upto(9) do |i| 1.upto(9) do |i|
result = "#{@username}-#{i}" result = "#{@username}-#{i}"
return result unless @nickname_conflict.include? result return result unless @nickname_conflict.include? result
end end
raise 'can`t get available nickname' raise 'can`t get available nickname'
else else
@username @username
end end
end end
def connect def connect
@recv = Thread.new do @recv = Thread.new do
EventMachine::run { EventMachine::run {
EventMachine::connect "bbs.66rpg.com", 9998, Client EventMachine::connect "bbs.66rpg.com", 9998, Client
} }
end end
end end
def im_connect def im_connect
Thread.new { Thread.new {
begin begin
@@im.allow_tls = false @@im.allow_tls = false
@@im.use_ssl = true @@im.use_ssl = true
@@im.connect('my-card.in', 5223) @@im.connect('my-card.in', 5223)
#ruby19/windows下 使用tls连接时会卡住 #ruby19/windows下 使用tls连接时会卡住
@@im.auth(@password) @@im.auth(@password)
@@im.send(Jabber::Presence.new.set_type(:available)) @@im.send(Jabber::Presence.new.set_type(:available))
begin begin
nickname = nickname() nickname = nickname()
@@im_room.join(Jabber::JID.new('lobby@conference.my-card.in/' + nickname)) @@im_room.join(Jabber::JID.new('lobby@conference.my-card.in/' + nickname))
rescue Jabber::ServerError => exception rescue Jabber::ServerError => exception
if exception.error.error == 'conflict' if exception.error.error == 'conflict'
@nickname_conflict << nickname @nickname_conflict << nickname
retry retry
end end
end end
Game_Event.push Game_Event::AllUsers.new @@im_room.roster.keys.collect { |nick| User.new(nick.to_sym, nick) } rescue p $! Game_Event.push Game_Event::AllUsers.new @@im_room.roster.keys.collect { |nick| User.new(nick.to_sym, nick) } rescue p $!
rescue StandardError => exception rescue StandardError => exception
$log.error('聊天连接出错') { exception } $log.error('聊天连接出错') { exception }
Game_Event.push(Game_Event::Chat.new(ChatMessage.new(User.new(:system, 'System'), '聊天服务器连接失败'))) Game_Event.push(Game_Event::Chat.new(ChatMessage.new(User.new(:system, 'System'), '聊天服务器连接失败')))
end end
} }
end end
def chat(chatmessage) def chat(chatmessage)
case chatmessage.channel case chatmessage.channel
when :lobby when :lobby
msg = Jabber::Message::new(nil, chatmessage.message) msg = Jabber::Message::new(nil, chatmessage.message)
@@im_room.send msg @@im_room.send msg
when User when User
msg = Jabber::Message::new(nil, chatmessage.message) msg = Jabber::Message::new(nil, chatmessage.message)
@@im_room.send msg, chatmessage.channel.id @@im_room.send msg, chatmessage.channel.id
#send(:chat, channel: chatmessage.channel.id, message: chatmessage.message, time: chatmessage.time) #send(:chat, channel: chatmessage.channel.id, message: chatmessage.message, time: chatmessage.time)
end end
end end
def host(room_name, room_config) def host(room_name, room_config)
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]
room.tag = room_config[:tag] room.tag = room_config[:tag]
room.password = room_config[:password] room.password = room_config[:password]
room.ot = room_config[:ot] room.ot = room_config[:ot]
room.lp = room_config[:lp] room.lp = room_config[:lp]
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) Game_Event.push Game_Event::Join.new(room)
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)
Game_Event.push Game_Event::Join.new(room) Game_Event.push Game_Event::Join.new(room)
end end
def refresh def refresh
send(:refresh) send(:refresh)
end end
def send(header, data=nil) def send(header, data=nil)
$log.info('发送消息') { {header: header, data: data} } $log.info('发送消息') { {header: header, data: data} }
Client::MycardChannel.push header: header, data: data Client::MycardChannel.push header: header, data: data
end end
def exit def exit
@recv.exit if @recv @recv.exit if @recv
@recv = nil @recv = nil
end end
def ygocore_path def ygocore_path
"ygocore/ygopro_vs.exe" "ygocore/ygopro_vs.exe"
end end
def self.register def self.register
Dialog.web @@config['register'] Dialog.web @@config['register']
end end
def server def server
@@config['server'] @@config['server']
end end
def port def port
@@config['port'] @@config['port']
end end
def server=(server) def server=(server)
@@config['server'] = server @@config['server'] = server
end end
def port=(port) def port=(port)
@@config['port'] = port @@config['port'] = port
end end
def self.run_ygocore(option, image_downloading=false) def self.run_ygocore(option, image_downloading=false)
if !image_downloading and !Update.images.empty? if !image_downloading and !Update.images.empty?
return Widget_Msgbox.new("加入房间", "卡图正在下载中,可能显示不出部分卡图", :ok => "确定") { run_ygocore(option, true) } return Widget_Msgbox.new("加入房间", "卡图正在下载中,可能显示不出部分卡图", :ok => "确定") { run_ygocore(option, true) }
end end
path = 'ygocore/ygopro_vs.exe' path = 'ygocore/ygopro_vs.exe'
Widget_Msgbox.new("ygocore", "正在启动ygocore") rescue nil Widget_Msgbox.new("ygocore", "正在启动ygocore") rescue nil
#写入配置文件并运行ygocore #写入配置文件并运行ygocore
Dir.chdir(File.dirname(path)) do Dir.chdir(File.dirname(path)) do
case option case option
when Room when Room
room = option room = option
room_name = if room.ot != 0 or room.lp != 8000 room_name = if room.ot != 0 or room.lp != 8000
mode = case when room.match? then mode = case when room.match? then
1; when room.tag? then 1; when room.tag? then
2 2
else else
0 0
end end
room_name = "#{room.ot}#{mode}FFF#{room.lp},5,1,#{room.name}" room_name = "#{room.ot}#{mode}FFF#{room.lp},5,1,#{room.name}"
elsif room.tag? elsif room.tag?
"T#" + room.name "T#" + room.name
elsif room.pvp? and room.match? elsif room.pvp? and room.match?
"PM#" + room.name "PM#" + room.name
elsif room.pvp? elsif room.pvp?
"P#" + room.name "P#" + room.name
elsif room.match? elsif room.match?
"M#" + room.name "M#" + room.name
else else
room.name room.name
end end
if room.password and !room.password.empty? if room.password and !room.password.empty?
room_name += "$" + room.password room_name += "$" + room.password
end end
system_conf = {} system_conf = {}
begin begin
IO.readlines('system.conf').each do |line| IO.readlines('system.conf').each do |line|
line.force_encoding "UTF-8" line.force_encoding "UTF-8"
next if line[0, 1] == '#' next if line[0, 1] == '#'
field, contents = line.chomp.split(' = ', 2) field, contents = line.chomp.split(' = ', 2)
system_conf[field] = contents system_conf[field] = contents
end end
rescue rescue
system_conf['antialias'] = 2 system_conf['antialias'] = 2
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'
end end
(system_conf['nickname'] = "#{$game.user.name}#{"$" unless $game.password.nil? or $game.password.empty?}#{$game.password}") rescue nil (system_conf['nickname'] = "#{$game.user.name}#{"$" unless $game.password.nil? or $game.password.empty?}#{$game.password}") rescue nil
system_conf['lastip'] = $game.server system_conf['lastip'] = $game.server
system_conf['lastport'] = $game.port.to_s system_conf['lastport'] = $game.port.to_s
system_conf['roompass'] = room_name system_conf['roompass'] = room_name
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") }
args = '-j' args = '-j'
when :replay when :replay
args = '-r' args = '-r'
when :deck when :deck
args = '-d' args = '-d'
when String when String
system_conf = {} system_conf = {}
begin begin
IO.readlines('system.conf').each do |line| IO.readlines('system.conf').each do |line|
line.force_encoding "UTF-8" line.force_encoding "UTF-8"
next if line[0, 1] == '#' next if line[0, 1] == '#'
field, contents = line.chomp.split(' = ', 2) field, contents = line.chomp.split(' = ', 2)
system_conf[field] = contents system_conf[field] = contents
end end
rescue rescue
system_conf['antialias'] = 2 system_conf['antialias'] = 2
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'
end end
system_conf['lastdeck'] = option system_conf['lastdeck'] = option
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") }
args = '-d' args = '-d'
end end
IO.popen("ygopro_vs.exe #{args}") IO.popen("ygopro_vs.exe #{args}")
WM.iconify rescue nil WM.iconify rescue nil
end end
Widget_Msgbox.destroy rescue nil Widget_Msgbox.destroy rescue nil
end end
def self.replay(file, skip_image_downloading = false) def self.replay(file, skip_image_downloading = false)
require 'fileutils' require 'fileutils'
FileUtils.mv Dir.glob('ygocore/replay/*.yrp'), 'replay/' FileUtils.mv Dir.glob('ygocore/replay/*.yrp'), 'replay/'
FileUtils.copy_file(file, "ygocore/replay/#{File.basename(file)}") FileUtils.copy_file(file, "ygocore/replay/#{File.basename(file)}")
run_ygocore(:replay, skip_image_downloading) run_ygocore(:replay, skip_image_downloading)
end end
private 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
open(@@config['api']) do |file| 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, @@config['index'], nil) announcements << Announcement.new(title, @@config['index'], nil)
end end
$config['ygocore']['announcements'].replace announcements $config['ygocore']['announcements'].replace announcements
Config.save Config.save
end end
rescue Exception => exception rescue Exception => exception
$log.error('公告读取失败') { [exception.inspect, *exception.backtrace].collect { |str| str.encode("UTF-8") }.join("\n") } $log.error('公告读取失败') { [exception.inspect, *exception.backtrace].collect { |str| str.encode("UTF-8") }.join("\n") }
end end
end end
end end
module Client module Client
MycardChannel = EM::Channel.new MycardChannel = EM::Channel.new
include EM::P::ObjectProtocol include EM::P::ObjectProtocol
def post_init def post_init
send_object header: :login, data: {name: $game.username, password: $game.password} send_object header: :login, data: {name: $game.username, password: $game.password}
MycardChannel.subscribe { |msg| send_object(msg) } MycardChannel.subscribe { |msg| send_object(msg) }
end end
def receive_object obj def receive_object obj
$log.info('收到消息') { obj.inspect } $log.info('收到消息') { obj.inspect }
Game_Event.push Game_Event.parse obj[:header], obj[:data] Game_Event.push Game_Event.parse obj[:header], obj[:data]
end end
def unbind def unbind
Game_Event.push Game_Event::Error.new('ygocore', '网络连接中断', true) Game_Event.push Game_Event::Error.new('ygocore', '网络连接中断', true)
end end
end end
get_announcements get_announcements
end end
\ No newline at end of file
class User class User
attr_reader :certified attr_reader :certified
def initialize(id, name = "", certified = true) def initialize(id, name = "", certified = true)
@id = id @id = id
@name = name @name = name
@certified = certified @certified = certified
end end
def set(id, name = :keep, certified = :keep) def set(id, name = :keep, certified = :keep)
@id = id unless id == :keep @id = id unless id == :keep
@name = name unless name == :keep @name = name unless name == :keep
@certified = certified unless certified == :keep @certified = certified unless certified == :keep
end end
def color def color
@certified ? [0,0,0] : [128,128,128] @certified ? [0,0,0] : [128,128,128]
end end
def space def space
if @certified if @certified
Dialog.web "http://my-card.in/users/#{CGI.escape @id.to_s}" Dialog.web "http://my-card.in/users/#{CGI.escape @id.to_s}"
else else
Widget_Msgbox.new("查看资料", "用户#{@name}没有注册", :ok => "确定") Widget_Msgbox.new("查看资料", "用户#{@name}没有注册", :ok => "确定")
end end
end end
def avatar(size = :small) def avatar(size = :small)
cache = "graphics/avatars/mycard_#{@id}_#{size}.png" cache = "graphics/avatars/mycard_#{@id}_#{size}.png"
result = Surface.load(cache) rescue Surface.load("graphics/avatars/loading_#{size}.gif") result = Surface.load(cache) rescue Surface.load("graphics/avatars/loading_#{size}.gif")
scene = $scene scene = $scene
if block_given? if block_given?
yield result yield result
Thread.new do Thread.new do
require 'cgi' require 'cgi'
open("http://my-card.in/users/#{CGI.escape @id.to_s}.png", 'rb') {|io|open(cache, 'wb') {|c|c.write io.read}} rescue cache = "graphics/avatars/noavatar_#{size}.gif" open("http://my-card.in/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 (yield Surface.load(cache) if scene == $scene) rescue nil
end end
else else
result result
end end
end end
end end
class Window_Login class Window_Login
def clicked def clicked
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
$config[$config['game']]['password'] = @remember_password.checked? ? @password_inputbox.value : nil $config[$config['game']]['password'] = @remember_password.checked? ? @password_inputbox.value : nil
Config.save Config.save
$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
Ygocore.register Ygocore.register
@last_clicked = Time.now @last_clicked = Time.now
when :replay when :replay
file = Dialog.get_open_file("播放录像", "ygocore录像 (*.yrp)" => "*.yrp") file = Dialog.get_open_file("播放录像", "ygocore录像 (*.yrp)" => "*.yrp")
if !file.empty? and File.file? file if !file.empty? and File.file? file
Ygocore.replay file Ygocore.replay file
end end
@last_clicked = Time.now @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