Skip to content

Instantly share code, notes, and snippets.

@amirrajan
Created February 15, 2023 20:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save amirrajan/b91c28ccec59d39fc70c4f14b074d03e to your computer and use it in GitHub Desktop.
Save amirrajan/b91c28ccec59d39fc70c4f14b074d03e to your computer and use it in GitHub Desktop.
Mildly Interesting RTS - Game Proxy
class GameProxy
attr_accessor :delegate, :session, :game
def initialize
@peer = MCPeerID.alloc.initWithDisplayName UIDevice.currentDevice.name
@session = MCSession.alloc.initWithPeer @peer
@advertiser = MCAdvertiserAssistant.alloc.initWithServiceType 'MIRTS', discoveryInfo: nil, session: @session
@connected = false
@session.delegate = self
end
def start_advertising
return if @advertising
@advertising = true
@advertiser.start
end
def stop_advertising
return unless @advertising
@advertising = false
@advertiser.stop
end
def connected?
@connected
end
def disconnect
@session.disconnect
end
def delegate_proxy_disconnected
@delegate.proxy_disconnected
end
def delegate_proxy_connecting
@delegate.proxy_connecting
end
def proxy_connected
@delegate.proxy_connected
end
def session session, peer: p, didChangeState: state
case state
when 0
performSelectorOnMainThread 'delegate_proxy_disconnected',
withObject: nil,
waitUntilDone: true
when 1
performSelectorOnMainThread 'delegate_proxy_connecting',
withObject: nil,
waitUntilDone: true
when 2
performSelectorOnMainThread 'proxy_connected',
withObject: nil,
waitUntilDone: true
end
@connected = true
end
def game
@delegate.proxy_game_instance || Game.new
end
def received_data hash
return unless hash
if hash['init_map']
selected_map = Maps.all_maps.find_all { |m| m.id == hash['init_map']['id'].to_sym }.first
game_speed = hash['init_map']['game_speed']
supply_limit = hash['init_map']['supply_limit']
if !hash['version']
@delegate.proxy_incompatible
send_incompatible
elsif hash['version'] != Game.version
@delegate.proxy_incompatible
send_incompatible
else
@delegate.proxy_begin_game selected_map, game_speed, supply_limit, hash['veteran_content']
end
elsif hash['cast_haste']
game.cast_haste hash['cast_haste']['player'],
hash['cast_haste']['x'],
hash['cast_haste']['y']
send_game_data game
elsif hash['send_nukes']
game.send_nukes_not_stasis hash['send_nukes']['player'],
hash['send_nukes']['x'],
hash['send_nukes']['y']
send_game_data game
elsif hash['send_paratroopers']
game.send_paratroopers hash['send_paratroopers']['player'],
hash['send_paratroopers']['x'],
hash['send_paratroopers']['y']
send_game_data game
elsif hash['cast_clone']
game.cast_clone hash['cast_clone']['player'],
hash['cast_clone']['x'],
hash['cast_clone']['y']
send_game_data game
elsif hash['cast_taunt']
game.cast_taunt hash['cast_taunt']['player'],
hash['cast_taunt']['x'],
hash['cast_taunt']['y']
elsif hash['cast_bunker']
game.cast_bunker hash['cast_bunker']['player'],
hash['cast_bunker']['x'],
hash['cast_bunker']['y']
send_game_data game
elsif hash['cast_stasis']
game.cast_stasis hash['cast_stasis']['player'],
hash['cast_stasis']['x'],
hash['cast_stasis']['y']
send_game_data game
elsif hash['forfeit']
game.forfeit hash['forfeit']['player']
elsif hash['move']
if !hash['version']
@delegate.proxy_incompatible
elsif hash['version'] != Game.version
@delegate.proxy_incompatible
else
player = hash['move']['player']
from_x = hash['move']['from_x']
from_y = hash['move']['from_y']
to_x = hash['move']['to_x']
to_y = hash['move']['to_y']
game.move_from_to player, from_x, from_y, to_x, to_y
end
elsif hash['player_units']
return unless game
return unless game.player_units
game.tick_count = hash['tick_count']
game.countdown = hash['countdown']
game.player_units.clear
hash['player_units'].each do |unit_dto|
game.player_units << unit_from_dto(unit_dto)
end
game.control_points = control_points_from_dto hash['control_points']
game.paratroopers[1] = hash['paratroopers']['1']
game.paratroopers[2] = hash['paratroopers']['2']
game.paratroopers[3] = hash['paratroopers']['3']
game.paratroopers_counts[1] = hash['paratroopers_counts']['1']
game.paratroopers_counts[2] = hash['paratroopers_counts']['2']
game.ticks_before_paratroopers_player = hash['ticks_before_paratroopers_player']
game.number_of_paratroopers_to_add_player = hash['number_of_paratroopers_to_add_player']
game.ticks_before_paratroopers_opponent = hash['ticks_before_paratroopers_opponent']
game.number_of_paratroopers_to_add_opponent = hash['number_of_paratroopers_to_add_opponent']
game.nukes[1] = hash['nukes']['1']
game.nukes[2] = hash['nukes']['2']
game.haste[1] = hash['haste']['1']
game.haste[2] = hash['haste']['2']
game.clone[1] = hash['clone']['1']
game.clone[2] = hash['clone']['2']
game.taunt[1] = hash['taunt']['1']
game.taunt[2] = hash['taunt']['2']
game.bunker_timer[1] = hash['bunker_timer']['1']
game.bunker_timer[2] = hash['bunker_timer']['2']
game.stasis[1] = hash['stasis']['1']
game.stasis[2] = hash['stasis']['2']
game.game_speed = hash['game_speed']
game.supply_limit = hash['supply_limit']
game.update_edges = hash['update_edges']
elsif hash['incompatible']
@delegate.proxy_incompatible
end
end
def unit_from_dto dto
{
id: dto['id'],
x: dto['x'],
y: dto['y'],
player: dto['player'],
to_x: dto['to_x'],
to_y: dto['to_y'],
eta: dto['eta'],
hp: dto['hp'],
warping: dto['warping'],
warp_drive_eta: dto['warp_drive_eta'],
timestamp: dto['timestamp'],
is_paratrooper: dto['is_paratrooper'],
attack_count: dto['attack_count'],
last_attacked: dto['last_attacked']
}
end
def control_points_from_dto dto
result = {}
dto.each do |k, v|
tokens = k.split ','
sub_dto = {}
sub_dto[:owner] = v['owner'] if v['owner']
sub_dto[:next_spawn] = v['next_spawn'] if v['next_spawn']
sub_dto[:capture_at] = v['capture_at'] if v['capture_at']
sub_dto[:contested_by] = v['contested_by'] if v['contested_by']
sub_dto[:x] = v['x']
sub_dto[:y] = v['y']
sub_dto[:nuked] = v['nuked']
sub_dto[:taunted] = v['taunted']
sub_dto[:last_taunt_by] = v['last_taunt_by']
sub_dto[:haste] = v['haste']
sub_dto[:cloned] = v['cloned']
sub_dto[:taunt] = v['taunt']
sub_dto[:bunker] = v['bunker']
sub_dto[:stasis] = v['stasis']
result[[tokens[0].to_i, tokens[1].to_i]] = sub_dto
end
result
end
def session session, didReceiveData: data, fromPeer: peer
performSelectorOnMainThread 'received_data:',
withObject: JSON.parse(NSString.alloc.initWithData(data, encoding: 4)),
waitUntilDone: false
end
def send_data hash
@session.sendData JSON.generate(hash).dataUsingEncoding(NSUTF8StringEncoding),
toPeers: @session.connectedPeers,
withMode: 0,
error: nil
end
def send_incompatible
return unless connected?
send_data(
{
incompatible: true
}
)
end
def content_unlocked?
GameState.veteran_content_unlocked?
end
def send_init_game map_id, game_speed, supply_limit
return unless connected?
send_data(
{
init_map: {
id: map_id,
game_speed: game_speed,
supply_limit: supply_limit
},
version: Game.version,
veteran_content: content_unlocked?
}
)
end
def send_game_data game
return unless connected?
send_data(
{
tick_count: game.tick_count,
countdown: game.countdown,
player_units: game.player_units,
control_points: to_control_points_dto(game),
paratroopers: {
'1' => game.paratroopers[1],
'2' => game.paratroopers[2],
'3' => game.paratroopers[3]
},
paratroopers_counts: {
'1' => game.paratroopers_counts[1],
'2' => game.paratroopers_counts[2],
},
nukes: {
'1' => game.nukes[1],
'2' => game.nukes[2]
},
haste: {
'1' => game.haste[1],
'2' => game.haste[2]
},
clone: {
'1' => game.clone[1],
'2' => game.clone[2]
},
taunt: {
'1' => game.taunt[1],
'2' => game.taunt[2]
},
bunker_timer: {
'1' => game.bunker_timer[1],
'2' => game.bunker_timer[2]
},
stasis: {
'1' => game.stasis[1],
'2' => game.stasis[2]
},
version: Game.version,
ticks_before_paratroopers_player: game.ticks_before_paratroopers_player,
number_of_paratroopers_to_add_player: game.number_of_paratroopers_to_add_player,
ticks_before_paratroopers_opponent: game.ticks_before_paratroopers_opponent,
number_of_paratroopers_to_add_opponent: game.number_of_paratroopers_to_add_opponent,
game_speed: game.game_speed,
supply_limit: game.supply_limit,
update_edges: game.update_edges
}
)
end
def to_control_points_dto game
result = {}
game.control_points.each do |k, v|
result["#{k[0]},#{k[1]}"] = v
end
result
end
def send_forfeit player
return unless connected?
send_data(
{
forfeit: { player: player }
}
)
end
def cast_haste player, x, y
return unless connected?
send_data(
{
cast_haste: {
player: player,
x: x,
y: y
}
}
)
end
def cast_clone player, x, y
return unless connected?
send_data(
{
cast_clone: {
player: player,
x: x,
y: y
}
}
)
end
def cast_taunt player, x, y
return unless connected?
send_data(
{
cast_taunt: {
player: player,
x: x,
y: y
}
}
)
end
def cast_stasis player, x, y
return unless connected?
send_data(
{
cast_stasis: {
player: player,
x: x,
y: y
}
}
)
end
def send_nukes player, x, y
return unless connected?
send_data(
{
send_nukes: {
player: player,
x: x,
y: y
}
}
)
end
def send_paratroopers player, x, y
return unless connected?
send_data(
{
send_paratroopers: {
player: player,
x: x,
y: y
}
}
)
end
def cast_bunker player, x, y
return unless connected?
send_data(
{
cast_bunker: {
player: player,
x: x,
y: y
}
}
)
end
def send_move player, from_x, from_y, to_x, to_y
return unless connected?
send_data(
{
move: {
player: player,
from_x: from_x,
from_y: from_y,
to_x: to_x,
to_y: to_y
},
version: Game.version
}
)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment