settlers 0.2.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.rdoc +6 -6
- data/bin/settlers +15 -3
- data/{resources/jsettlers-1.0.6 → data/settlers/jsettlers-1.1.09}/COPYING.txt +340 -340
- data/data/settlers/jsettlers-1.1.09/JSettlers.jar +0 -0
- data/{resources/jsettlers-1.0.6 → data/settlers/jsettlers-1.1.09}/README.txt +80 -45
- data/data/settlers/jsettlers-1.1.09/VERSIONS.txt +225 -0
- data/lib/settlers.rb +28 -3
- data/lib/settlers/address.rb +23 -0
- data/lib/settlers/application.rb +38 -103
- data/lib/settlers/bonjour.rb +35 -0
- data/lib/settlers/client.rb +11 -0
- data/lib/settlers/collector.rb +24 -0
- data/lib/settlers/java.rb +39 -0
- data/lib/settlers/observer.rb +7 -0
- data/lib/settlers/server.rb +25 -0
- data/lib/settlers/ui.rb +30 -0
- metadata +62 -33
- data/Rakefile +0 -10
- data/lib/settlers/jar.rb +0 -17
- data/lib/settlers/java_command.rb +0 -22
- data/resources/jsettlers-1.0.6/JSettlers.jar +0 -0
- data/resources/jsettlers-1.0.6/JSettlersServer.jar +0 -0
- data/resources/jsettlers-1.0.6/VERSIONS.txt +0 -50
- data/settlers.gemspec +0 -38
data/lib/settlers.rb
CHANGED
@@ -1,3 +1,28 @@
|
|
1
|
-
require '
|
2
|
-
require '
|
3
|
-
require '
|
1
|
+
require 'pathname'
|
2
|
+
require 'rbconfig'
|
3
|
+
require 'rbconfig/datadir'
|
4
|
+
|
5
|
+
module Settlers
|
6
|
+
VERSION = '0.3.0'
|
7
|
+
|
8
|
+
autoload :Address, 'settlers/address'
|
9
|
+
autoload :Application, 'settlers/application'
|
10
|
+
autoload :Bonjour, 'settlers/bonjour'
|
11
|
+
autoload :Client, 'settlers/client'
|
12
|
+
autoload :Collector, 'settlers/collector'
|
13
|
+
autoload :Java, 'settlers/java'
|
14
|
+
autoload :Observer, 'settlers/observer'
|
15
|
+
autoload :Server, 'settlers/server'
|
16
|
+
autoload :UI, 'settlers/ui'
|
17
|
+
|
18
|
+
def self.datadir
|
19
|
+
@@datadir ||= begin
|
20
|
+
datadir = RbConfig.datadir('settlers')
|
21
|
+
if !File.exist?(datadir)
|
22
|
+
warn "#{datadir} does not exist. Trying again with data directory relative to __FILE__."
|
23
|
+
datadir = File.expand_path('../../data/settlers', __FILE__)
|
24
|
+
end
|
25
|
+
Pathname.new(datadir)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'ipaddr'
|
2
|
+
|
3
|
+
module Settlers
|
4
|
+
class Address < Struct.new(:name, :host, :port)
|
5
|
+
include Comparable
|
6
|
+
|
7
|
+
def self.from(reply, info)
|
8
|
+
new reply.name, info.address, reply.port
|
9
|
+
end
|
10
|
+
|
11
|
+
def <=>(other)
|
12
|
+
[name, ip, port] <=> [other.name, other.ip, other.port]
|
13
|
+
end
|
14
|
+
|
15
|
+
def ip
|
16
|
+
IPAddr.new(host)
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_s
|
20
|
+
"#{name} (#{host}:#{port})"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/settlers/application.rb
CHANGED
@@ -1,131 +1,66 @@
|
|
1
|
-
require 'optparse'
|
2
|
-
require 'set'
|
3
|
-
require 'shellwords'
|
4
|
-
|
5
|
-
require 'rubygems'
|
6
|
-
require 'dnssd'
|
7
|
-
require 'highline/import'
|
8
|
-
|
9
1
|
module Settlers
|
10
2
|
class Application
|
11
|
-
|
12
|
-
|
13
|
-
def initialize(*args)
|
14
|
-
self.server = Server.new
|
15
|
-
self.client = Client.new
|
16
|
-
self.style = StandaloneGame
|
17
|
-
parse_options(args)
|
18
|
-
end
|
3
|
+
DEFAULT_PORT = 7777
|
19
4
|
|
20
|
-
def
|
21
|
-
|
22
|
-
|
5
|
+
def initialize
|
6
|
+
@collector = Collector.new
|
7
|
+
@ui = UI.new
|
23
8
|
|
24
|
-
|
25
|
-
server.start
|
26
|
-
end
|
9
|
+
@defaults = %w(--server)
|
27
10
|
|
28
|
-
|
29
|
-
|
30
|
-
|
11
|
+
@options = OptionParser.new do |opts|
|
12
|
+
opts.banner = "Usage: #{File.basename($0)} [--client]"
|
13
|
+
opts.separator ''
|
14
|
+
opts.version = Settlers::VERSION
|
31
15
|
|
32
|
-
|
33
|
-
|
34
|
-
|
16
|
+
opts.on('-c', '--client', 'Discover and connect to a game server.') do
|
17
|
+
@announcer = NullObject.new
|
18
|
+
@discoverer = Bonjour.new
|
19
|
+
@server = NullObject.new
|
20
|
+
end
|
35
21
|
|
36
|
-
|
22
|
+
opts.on('-s', '--server[=PORT]', Integer, 'Launch, announce, and connect to a game server.', ". PORT defaults to #{DEFAULT_PORT}.") do |port|
|
23
|
+
@announcer = Bonjour.new
|
24
|
+
@discoverer = NullObject.new
|
25
|
+
@server = Server.new(port || DEFAULT_PORT)
|
26
|
+
end
|
37
27
|
|
38
|
-
|
39
|
-
|
40
|
-
OptionParser.new do |opts|
|
41
|
-
opts.on('-c', '--client') { self.style = BonjourClientGame }
|
42
|
-
opts.parse!(args)
|
28
|
+
opts.separator 'Defaults:'
|
29
|
+
opts.separator "#{opts.summary_indent}#{@defaults.join(' ')}"
|
43
30
|
end
|
44
31
|
end
|
45
32
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
33
|
+
def run(args)
|
34
|
+
begin
|
35
|
+
@options.parse!(@defaults.dup.concat(args))
|
36
|
+
rescue OptionParser::ParseError
|
37
|
+
@options.abort($!)
|
50
38
|
end
|
51
|
-
end
|
52
39
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
end
|
57
|
-
end
|
40
|
+
@server.add_observer(@announcer)
|
41
|
+
@server.add_observer(@collector)
|
42
|
+
@server.start
|
58
43
|
|
59
|
-
|
60
|
-
|
44
|
+
@discoverer.add_observer(@collector)
|
45
|
+
@discoverer.start
|
61
46
|
|
62
|
-
|
63
|
-
|
64
|
-
servers << RemoteServer.new(reply.name, resolve_reply.target, resolve_reply.port)
|
65
|
-
end
|
47
|
+
@ui.choose_server(@collector) do |address|
|
48
|
+
Client.new(address).start
|
66
49
|
end
|
67
|
-
|
68
|
-
puts 'Looking for settlers servers nearby...'
|
69
|
-
sleep timeout
|
70
|
-
dns.stop
|
71
|
-
|
72
|
-
return servers
|
73
50
|
end
|
74
51
|
|
75
|
-
|
76
|
-
# Maybe we can change these to attr_writer as we'd like to make them command-line configurable.
|
77
|
-
attr_reader :name, :host, :port, :startup_delay, :maximum_connections, :username, :password, :robot_names
|
78
|
-
|
79
|
-
def initialize
|
80
|
-
@name = "#{`hostname -s`.chomp}-#{`whoami`.chomp}"
|
81
|
-
@host = 'localhost'
|
82
|
-
@port = 8880
|
83
|
-
@startup_delay = 4
|
84
|
-
@maximum_connections = 12
|
85
|
-
@username = 'root'
|
86
|
-
@password = ''
|
87
|
-
@robot_names = %w(Leonardo Humperdink Elwood)
|
88
|
-
end
|
89
|
-
|
90
|
-
def start
|
91
|
-
announce
|
92
|
-
serve
|
93
|
-
sleep(startup_delay)
|
94
|
-
start_robots
|
95
|
-
end
|
96
|
-
|
97
|
-
private
|
98
|
-
|
99
|
-
def announce
|
100
|
-
# Maybe it would be nice to include a TextRecord here providing something of a description?
|
101
|
-
DNSSD.register(name, '_settlers._tcp', 'local', port) do |rr|
|
102
|
-
puts "Announcing settlers server available on port #{port}."
|
103
|
-
end
|
104
|
-
end
|
52
|
+
private
|
105
53
|
|
106
|
-
|
107
|
-
|
108
|
-
Jar.new('JSettlersServer.jar').running('soc.server.SOCServer').start(port, maximum_connections, username, Shellwords.escape(password))
|
54
|
+
class NullObject #:nodoc:
|
55
|
+
def add_observer(observer)
|
109
56
|
end
|
110
57
|
|
111
|
-
def
|
112
|
-
robot_names.each do |name|
|
113
|
-
# TODO move the Shellwords.escape call inside of JavaCommand.start
|
114
|
-
Jar.new('JSettlersServer.jar').running('soc.robot.SOCRobotClient').start(host, port, name, Shellwords.escape(password))
|
115
|
-
end
|
58
|
+
def update(*args)
|
116
59
|
end
|
117
|
-
end
|
118
60
|
|
119
|
-
|
120
|
-
def to_s
|
121
|
-
"#{name} (#{host}:#{port})"
|
61
|
+
def start
|
122
62
|
end
|
123
63
|
end
|
124
64
|
|
125
|
-
class Client
|
126
|
-
def start(server)
|
127
|
-
Jar.new('JSettlers.jar').running('soc.client.SOCPlayerClient').run(server.host, server.port)
|
128
|
-
end
|
129
|
-
end
|
130
65
|
end
|
131
66
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'dnssd'
|
2
|
+
require 'observer'
|
3
|
+
|
4
|
+
module Settlers
|
5
|
+
class Bonjour
|
6
|
+
TYPE = '_settlers._tcp'
|
7
|
+
|
8
|
+
include Observable
|
9
|
+
include Observer
|
10
|
+
|
11
|
+
# To confirm registration is working, run `mDNS -B _settlers._tcp`.
|
12
|
+
def server_exists_at(address)
|
13
|
+
DNSSD.register!(address.name, TYPE, nil, address.port)
|
14
|
+
end
|
15
|
+
|
16
|
+
def start(timeout=5)
|
17
|
+
puts "Looking for servers for up to #{timeout} seconds..."
|
18
|
+
|
19
|
+
DNSSD.browse(TYPE) do |browse|
|
20
|
+
DNSSD.resolve(browse) do |reply|
|
21
|
+
DNSSD.getaddrinfo!(reply.target, DNSSD::Service::IPv4) do |info|
|
22
|
+
changed
|
23
|
+
notify_observers :server_exists_at, Address.from(reply, info)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
sleep timeout
|
29
|
+
end
|
30
|
+
|
31
|
+
def DNSSD.getaddrinfo!(*args, &block) #:nodoc:
|
32
|
+
run(DNSSD::Service.new, :getaddrinfo, *args, &block)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'set'
|
2
|
+
|
3
|
+
module Settlers
|
4
|
+
class Collector
|
5
|
+
include Enumerable
|
6
|
+
include Observer
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@addresses = Set.new
|
10
|
+
end
|
11
|
+
|
12
|
+
def server_exists_at(address)
|
13
|
+
@addresses.add(address)
|
14
|
+
end
|
15
|
+
|
16
|
+
def each(&block)
|
17
|
+
@addresses.sort.each(&block)
|
18
|
+
end
|
19
|
+
|
20
|
+
def size
|
21
|
+
@addresses.size
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Settlers
|
2
|
+
class Java
|
3
|
+
def self.server
|
4
|
+
new('soc.server.SOCServer')
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.client
|
8
|
+
new('soc.client.SOCPlayerClient')
|
9
|
+
end
|
10
|
+
|
11
|
+
JAR = Settlers.datadir.join('jsettlers-1.1.09', 'JSettlers.jar')
|
12
|
+
|
13
|
+
def initialize(class_name)
|
14
|
+
@class_name = class_name
|
15
|
+
end
|
16
|
+
|
17
|
+
def run(*args)
|
18
|
+
pid = quietly_fork(args)
|
19
|
+
Process.waitpid(pid)
|
20
|
+
end
|
21
|
+
|
22
|
+
def start(*args)
|
23
|
+
pid = quietly_fork(args)
|
24
|
+
at_exit { Process.kill 'INT', pid }
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def quietly_fork(args)
|
30
|
+
args.map! { |arg| arg.to_s }
|
31
|
+
|
32
|
+
fork do
|
33
|
+
STDOUT.reopen '/dev/null'
|
34
|
+
STDERR.reopen '/dev/null'
|
35
|
+
exec 'java', '-cp', JAR, @class_name, *args
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'observer'
|
2
|
+
|
3
|
+
module Settlers
|
4
|
+
class Server
|
5
|
+
include Observable
|
6
|
+
|
7
|
+
def initialize(port)
|
8
|
+
@address = Address.new(name, '127.0.0.1', port)
|
9
|
+
end
|
10
|
+
|
11
|
+
def start
|
12
|
+
Java.server.start(@address.port, 10, 'root', '')
|
13
|
+
changed
|
14
|
+
notify_observers :server_exists_at, @address
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def name
|
20
|
+
login = Etc.getlogin
|
21
|
+
name = Etc.getpwnam(login).gecos
|
22
|
+
"#{name}'s Settlers Server"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/settlers/ui.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'highline'
|
2
|
+
|
3
|
+
module Settlers
|
4
|
+
class UI
|
5
|
+
def initialize
|
6
|
+
@console = HighLine.new
|
7
|
+
end
|
8
|
+
|
9
|
+
def choose_server(list)
|
10
|
+
yield case list.size
|
11
|
+
when 0
|
12
|
+
abort 'No servers to choose from.'
|
13
|
+
when 1
|
14
|
+
list.first
|
15
|
+
else
|
16
|
+
choose_from_many(list)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def choose_from_many(list)
|
23
|
+
begin
|
24
|
+
@console.choose(*list)
|
25
|
+
rescue Interrupt
|
26
|
+
abort "\nGoodbye."
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: settlers
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
hash: 19
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 3
|
9
|
+
- 0
|
10
|
+
version: 0.3.0
|
5
11
|
platform: ruby
|
6
12
|
authors:
|
7
13
|
- Matthew Todd
|
@@ -9,39 +15,51 @@ autorequire:
|
|
9
15
|
bindir: bin
|
10
16
|
cert_chain: []
|
11
17
|
|
12
|
-
date: 2010-
|
13
|
-
default_executable:
|
18
|
+
date: 2010-06-18 00:00:00 +03:00
|
19
|
+
default_executable:
|
14
20
|
dependencies:
|
15
21
|
- !ruby/object:Gem::Dependency
|
16
|
-
|
17
|
-
|
18
|
-
version_requirement:
|
19
|
-
version_requirements: !ruby/object:Gem::Requirement
|
22
|
+
version_requirements: &id001 !ruby/object:Gem::Requirement
|
23
|
+
none: false
|
20
24
|
requirements:
|
21
25
|
- - ">="
|
22
26
|
- !ruby/object:Gem::Version
|
27
|
+
hash: 3
|
28
|
+
segments:
|
29
|
+
- 0
|
23
30
|
version: "0"
|
24
|
-
|
31
|
+
requirement: *id001
|
32
|
+
name: shoe
|
33
|
+
prerelease: false
|
34
|
+
type: :development
|
25
35
|
- !ruby/object:Gem::Dependency
|
26
|
-
|
27
|
-
|
28
|
-
version_requirement:
|
29
|
-
version_requirements: !ruby/object:Gem::Requirement
|
36
|
+
version_requirements: &id002 !ruby/object:Gem::Requirement
|
37
|
+
none: false
|
30
38
|
requirements:
|
31
39
|
- - ">="
|
32
40
|
- !ruby/object:Gem::Version
|
41
|
+
hash: 3
|
42
|
+
segments:
|
43
|
+
- 0
|
33
44
|
version: "0"
|
34
|
-
|
35
|
-
- !ruby/object:Gem::Dependency
|
45
|
+
requirement: *id002
|
36
46
|
name: highline
|
47
|
+
prerelease: false
|
37
48
|
type: :runtime
|
38
|
-
|
39
|
-
version_requirements: !ruby/object:Gem::Requirement
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
version_requirements: &id003 !ruby/object:Gem::Requirement
|
51
|
+
none: false
|
40
52
|
requirements:
|
41
53
|
- - ">="
|
42
54
|
- !ruby/object:Gem::Version
|
55
|
+
hash: 3
|
56
|
+
segments:
|
57
|
+
- 0
|
43
58
|
version: "0"
|
44
|
-
|
59
|
+
requirement: *id003
|
60
|
+
name: dnssd
|
61
|
+
prerelease: false
|
62
|
+
type: :runtime
|
45
63
|
description:
|
46
64
|
email: matthew.todd@gmail.com
|
47
65
|
executables:
|
@@ -51,21 +69,24 @@ extensions: []
|
|
51
69
|
extra_rdoc_files:
|
52
70
|
- README.rdoc
|
53
71
|
files:
|
54
|
-
- Rakefile
|
55
|
-
- settlers.gemspec
|
56
72
|
- README.rdoc
|
57
73
|
- bin/settlers
|
74
|
+
- data/settlers/jsettlers-1.1.09/COPYING.txt
|
75
|
+
- data/settlers/jsettlers-1.1.09/JSettlers.jar
|
76
|
+
- data/settlers/jsettlers-1.1.09/README.txt
|
77
|
+
- data/settlers/jsettlers-1.1.09/VERSIONS.txt
|
78
|
+
- lib/settlers/address.rb
|
58
79
|
- lib/settlers/application.rb
|
59
|
-
- lib/settlers/
|
60
|
-
- lib/settlers/
|
80
|
+
- lib/settlers/bonjour.rb
|
81
|
+
- lib/settlers/client.rb
|
82
|
+
- lib/settlers/collector.rb
|
83
|
+
- lib/settlers/java.rb
|
84
|
+
- lib/settlers/observer.rb
|
85
|
+
- lib/settlers/server.rb
|
86
|
+
- lib/settlers/ui.rb
|
61
87
|
- lib/settlers.rb
|
62
|
-
- resources/jsettlers-1.0.6/COPYING.txt
|
63
|
-
- resources/jsettlers-1.0.6/JSettlers.jar
|
64
|
-
- resources/jsettlers-1.0.6/JSettlersServer.jar
|
65
|
-
- resources/jsettlers-1.0.6/README.txt
|
66
|
-
- resources/jsettlers-1.0.6/VERSIONS.txt
|
67
88
|
has_rdoc: true
|
68
|
-
homepage:
|
89
|
+
homepage: http://github.com/matthewtodd/settlers
|
69
90
|
licenses: []
|
70
91
|
|
71
92
|
post_install_message:
|
@@ -73,26 +94,34 @@ rdoc_options:
|
|
73
94
|
- --main
|
74
95
|
- README.rdoc
|
75
96
|
- --title
|
76
|
-
- settlers-0.
|
97
|
+
- settlers-0.3.0
|
77
98
|
- --inline-source
|
99
|
+
- --webcvs
|
100
|
+
- http://github.com/matthewtodd/settlers/blob/v0.3.0/
|
78
101
|
require_paths:
|
79
102
|
- lib
|
80
103
|
required_ruby_version: !ruby/object:Gem::Requirement
|
104
|
+
none: false
|
81
105
|
requirements:
|
82
106
|
- - ">="
|
83
107
|
- !ruby/object:Gem::Version
|
108
|
+
hash: 3
|
109
|
+
segments:
|
110
|
+
- 0
|
84
111
|
version: "0"
|
85
|
-
version:
|
86
112
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
87
114
|
requirements:
|
88
115
|
- - ">="
|
89
116
|
- !ruby/object:Gem::Version
|
117
|
+
hash: 3
|
118
|
+
segments:
|
119
|
+
- 0
|
90
120
|
version: "0"
|
91
|
-
|
92
|
-
|
93
|
-
|
121
|
+
requirements:
|
122
|
+
- java
|
94
123
|
rubyforge_project:
|
95
|
-
rubygems_version: 1.3.
|
124
|
+
rubygems_version: 1.3.7
|
96
125
|
signing_key:
|
97
126
|
specification_version: 3
|
98
127
|
summary: Provides a simple command-line executable for playing Robb Thomas' JSettlers game.
|