class EventMachine::WebSocket::Connection

Constants

BATTLING
IDLE
MATCHING

Attributes

current_action[RW]
current_battle[RW]
current_friend_loginname[RW]
current_opponent[RW]
current_win_rounds[RW]
loginname[RW]
matching_retry_times[RW]
pvp1_wins[RW]
pvp_state[RW]

Public Instance Methods

battling!() click to toggle source
# File lib/ss/connection.rb, line 107
def battling!
  @pvp_state = BATTLING
end
cancel_matching(reason = nil) click to toggle source
# File lib/ss/connection.rb, line 71
def cancel_matching(reason = nil)
  if @pvp_state == MATCHING
    friend_loginname = @current_friend_loginname
    @pvp_state = IDLE
    @current_friend_loginname = nil
    send_message_matching_canceled(reason)

    friend_loginname
  end
end
escape_pvp() click to toggle source
# File lib/ss/connection.rb, line 82
def escape_pvp
  if @pvp_state == BATTLING && @current_opponent
    @current_opponent.win("#{@loginname} 逃跑了")
  end
end
logout(players, reason = nil) click to toggle source
# File lib/ss/connection.rb, line 29
def logout(players, reason = nil)
  if @loginname
    loginname = @loginname
    escape_pvp
    cancel_matching

    @loginname = nil
    @pvp1_wins = 0
    send_message_loggedout(reason)

    players.delete loginname
    puts "#{loginname} logged out, players.size: #{players.size}"

    loginname
  end
end
pvp1(players) click to toggle source

随机对战

# File lib/ss/connection.rb, line 47
def pvp1(players)
  if @loginname && players[@loginname]
    @pvp_state = MATCHING
    @matching_retry_times = 0
    send_message_pvp1_ready
    puts "#{@loginname} random battle ready, state: #{@pvp_state}"

    matching1(players)
  end
end
pvp2(friend_loginname, players) click to toggle source

好友对战

# File lib/ss/connection.rb, line 59
def pvp2(friend_loginname, players)
  if @loginname && players[@loginname] && friend_loginname && !friend_loginname.empty? && @loginname != friend_loginname
    @pvp_state = MATCHING
    @matching_retry_times = 0
    @current_friend_loginname = friend_loginname
    send_message_pvp2_ready friend_loginname
    puts "#{@loginname} friend battle ready, state: #{@pvp_state}"

    matching2(players)
  end
end
send_message_loggedout(reason = nil) click to toggle source
# File lib/ss/connection.rb, line 119
def send_message_loggedout(reason = nil)
  send_message 'loggedout', reason || '已退出'
end
send_message_lost() click to toggle source
# File lib/ss/connection.rb, line 154
def send_message_lost
  send_message 'lost', '输了。'
end
send_message_matched(instruction) click to toggle source
# File lib/ss/connection.rb, line 141
def send_message_matched(instruction)
  send_message 'matched', "#{@loginname} 对 #{@current_opponent.loginname}, #{instruction}"
end
send_message_matching() click to toggle source
# File lib/ss/connection.rb, line 131
def send_message_matching
  send_message 'matching', '.'
end
send_message_matching_canceled(reason = nil) click to toggle source
# File lib/ss/connection.rb, line 135
def send_message_matching_canceled(reason = nil)
  part = '匹配被取消'
  send_message 'matching-canceled',
    reason ? [ reason, part ].join(', ') : part
end
send_message_pvp1_ready() click to toggle source
# File lib/ss/connection.rb, line 123
def send_message_pvp1_ready
  send_message 'pvp-ready', '匹配对手中'
end
send_message_pvp2_ready(friend_loginname) click to toggle source
# File lib/ss/connection.rb, line 127
def send_message_pvp2_ready(friend_loginname)
  send_message 'pvp-ready', "匹配 #{friend_loginname} 中"
end
send_message_round_finished(round, compare) click to toggle source
# File lib/ss/connection.rb, line 158
def send_message_round_finished(round, compare)
  send_message 'round-finished',
    [ round, compare, @loginname, @current_action, @current_win_rounds, @current_opponent.loginname, @current_opponent.current_action, @current_opponent.current_win_rounds ]
end
send_message_simple_logined() click to toggle source
# File lib/ss/connection.rb, line 115
def send_message_simple_logined
  send_message 'simple-logined', @loginname
end
send_message_welcome() click to toggle source
# File lib/ss/connection.rb, line 111
def send_message_welcome
  send_message 'msg1', "欢迎来到 石头剪子布 大战!"
end
send_message_won(reason = nil) click to toggle source
# File lib/ss/connection.rb, line 145
def send_message_won(reason = nil)
  word = '赢了!'
  send_message 'won', 
    [ 
      reason ? [ reason, word ].join(', ') : word, 
      @pvp1_wins
    ]
end
simple_login(loginname, players) click to toggle source
# File lib/ss/connection.rb, line 11
def simple_login(loginname, players)
  if loginname.nil? || loginname.empty?
    loginname = players['takafan'] ? 'ayumi' : 'takafan'
  end
  
  old_ws = players[loginname]
  if old_ws && old_ws != self
    old_ws.logout players, '你在别的地方登录了'
  end
  players[loginname] = self
  @loginname = loginname
  @current_opponent = nil
  @pvp_state = IDLE
  @pvp1_wins = 0
  send_message_simple_logined
  puts "#{loginname} logined, players.size: #{players.size}"
end
stjzb(action) click to toggle source
# File lib/ss/connection.rb, line 103
def stjzb(action)
  @current_battle.act(self, action) if @current_battle
end
win(reason = nil) click to toggle source
# File lib/ss/connection.rb, line 88
def win(reason = nil)
  @current_battle = nil
  @pvp_state = IDLE
  if @current_friend_loginname
    @current_friend_loginname = nil
  else
    @pvp1_wins += 1
  end
  send_message_won(reason)
  @current_opponent.current_battle = nil
  @current_opponent.pvp_state = IDLE
  @current_opponent.current_friend_loginname = nil
  @current_opponent.send_message_lost
end

Private Instance Methods

matching1(players) click to toggle source

pvp1匹配,隔3秒主动匹配1次,重试10次,不成功cancel

# File lib/ss/connection.rb, line 166
def matching1(players)
  EM.add_timer(3) {
    if @loginname && @pvp_state == MATCHING
      puts "#{@loginname} matching, retry: #{@matching_retry_times}"
      opponent = players.values.select{|_ws| _ws != self and _ws.pvp_state == MATCHING and _ws.current_friend_loginname.nil? }.sample
      if opponent
        StjzbServer::Stjzb.new(self, opponent)
      elsif @matching_retry_times < 10
        send_message_matching
        @matching_retry_times += 1
        matching1(players)
      else
        cancel_matching('没有找到对手')
        puts "no opponent, matching canceled, state: #{@pvp_state}"
      end
    else
      puts "ignore matching"
    end
  }
end
matching2(players) click to toggle source

pvp2匹配

# File lib/ss/connection.rb, line 188
def matching2(players)
  puts "#{@loginname} matching #{@current_friend_loginname}, retry: #{@matching_retry_times}"
  if @pvp_state == MATCHING
    opponent = players[@current_friend_loginname]
    if opponent && opponent.pvp_state == MATCHING && opponent.current_friend_loginname == @loginname
      StjzbServer::Stjzb.new(self, opponent)
    elsif @matching_retry_times < 10
      send_message_matching
      @matching_retry_times += 1
      EM.add_timer(3) {
        matching2(players)
      }
    else
      friend_loginname = cancel_matching("#{@current_friend_loginname} 没有反应")
      puts "#{friend_loginname} not pong, matching canceled, state: #{@pvp_state}"
    end
  else
    puts "ignore, state: #{@pvp_state}"
  end
end
send_message(act, msg) click to toggle source
# File lib/ss/connection.rb, line 209
def send_message(act, msg)
  send Oj.dump([ act, msg ])
end