Skip to content

Instantly share code, notes, and snippets.

@ioquatix
Created February 1, 2015 05:13
Show Gist options
  • Save ioquatix/0dc14ae7cb93ee4d3255 to your computer and use it in GitHub Desktop.
Save ioquatix/0dc14ae7cb93ee4d3255 to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby
require 'rubydns'
require 'rubydns/extensions/string'
INTERFACES = [
[:udp, '0.0.0.0', 5300],
[:tcp, '0.0.0.0', 5300]
]
Name = Resolv::DNS::Name
IN = Resolv::DNS::Resource::IN
# Use upstream DNS for name resolution.
UPSTREAM = RubyDNS::Resolver.new([[:udp, '8.8.8.8', 53], [:tcp, '8.8.8.8', 53]])
class PlayerState
def initialize(name)
@name = name
@x = @y = 0
@shouts = ["Hello"]
end
attr :name
attr_accessor :x
attr_accessor :y
attr :shouts
def inspect
"<PlayerState #{@name}>"
end
end
class GameState
KEYS = {
'w' => [0, 1],
's' => [0, -1],
'a' => [-1, 0],
'd' => [1, 0]
}
def initialize
@players = {}
@width = @height = 5
@map = @height.times.collect{[[]] * @width}
end
attr :players
def register(name)
player = @players[name] = PlayerState.new(name)
@map[player.x][player.y] << player
end
def move(username, input)
player = @players[username]
@map[player.x][player.y].delete(player)
input.each_char do |c|
direction = KEYS[c]
player.x = (player.x + direction[0]) % @width
player.y = (player.y + direction[1]) % @height
end
@map[player.x][player.y] << player
return "Moved #{player.x}, #{player.y}"
end
def shout(username, input)
player = @players[username]
puts @map.inspect
@map[player.x][player.y].each do |other_player|
puts "Shouted #{input.inspect} at #{other_player.name}"
other_player.shouts << input
end
return "Shouted #{input}"
end
end
# Start the RubyDNS server
RubyDNS.run_server(listen: INTERFACES) do
@logger.level = Logger::INFO
game_state = GameState.new
match(/([a-z]{3,8})\.register/, IN::TXT) do |transaction, match|
username = match[1]
puts game_state.players.inspect
if game_state.players.include? username
transaction.fail! :Refused
else
game_state.register(username)
transaction.respond!("Registered #{username}")
end
end
match(/([wsad]+)\.([a-z]{3,8})\.move/, IN::TXT) do |transaction, match|
input = match[1]
username = match[2]
puts "Input: #{input} Username: #{username}"
puts "Players: #{game_state.players.keys.inspect}"
if game_state.players.include? username
status = game_state.move(username, input)
transaction.respond!(status)
else
transaction.fail! :Refused
end
end
match(/([a-z]{3,8})\.shouts/, IN::TXT) do |transaction, match|
username = match[1]
if game_state.players.include? username
shouts = game_state.players[username].shouts
transaction.respond!(*shouts)
else
transaction.fail! :Refused
end
end
match(/([a-z]{2,20})\.([a-z]{3,8})\.shout/, IN::TXT) do |transaction, match|
input = match[1]
username = match[2]
puts "Shout: #{input} Username: #{username}"
if game_state.players.include? username
status = game_state.shout(username, input)
transaction.respond!(status)
else
transaction.fail! :Refused
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment