netz 0.0.1

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.
@@ -0,0 +1,3 @@
1
+ tags
2
+ pkg
3
+ *.swp
@@ -0,0 +1,8 @@
1
+ = Netz
2
+ http://github.com/shawn42/netz/tree/master
3
+
4
+ == INSTALL
5
+ gem install netz
6
+
7
+ == TODO
8
+ more docs and examples
@@ -0,0 +1,22 @@
1
+ begin
2
+ require 'jeweler'
3
+ Jeweler::Tasks.new do |gem|
4
+ gem.name = "netz"
5
+ gem.rubyforge_project = "netz"
6
+ gem.summary = %Q{Networking library for use in games.}
7
+ gem.description = %Q{P2P Networking library for us in games. }
8
+ gem.email = "shawn42@gmail.com"
9
+ gem.homepage = "http://shawn42.github.com/netz"
10
+ gem.authors = ["Shawn Anderson"]
11
+ gem.add_development_dependency "rspec"
12
+ gem.add_development_dependency "jeweler"
13
+ gem.add_dependency 'gosu'
14
+ gem.add_dependency 'bundler'
15
+ gem.test_files = FileList['{spec,test}/**/*.rb']
16
+ end
17
+ Jeweler::GemcutterTasks.new
18
+ rescue LoadError
19
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
20
+ end
21
+
22
+ # vim: syntax=Ruby
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,7 @@
1
+ require 'thread'
2
+ require 'socket'
3
+ require 'netz/command'
4
+ require 'netz/broadcaster'
5
+ require 'netz/catcher'
6
+ require 'netz/safe_array'
7
+ require 'netz/client'
@@ -0,0 +1,31 @@
1
+ module Netz
2
+ class Broadcaster
3
+ attr_accessor :remote_clients, :command_channel
4
+
5
+ def initialize
6
+ @remote_clients = []
7
+ end
8
+
9
+ def run
10
+ Thread.new do
11
+ loop do
12
+ command = @command_channel.pop
13
+ push_to_peers command if command.local?
14
+ end
15
+ end
16
+ end
17
+
18
+ def push_to_peers(command)
19
+ # TODO add command buffering?
20
+ command.extend(CommandSerializer)
21
+
22
+ # write to clients
23
+ msg = command.serialize
24
+ puts msg
25
+ @remote_clients.each do |rc|
26
+ rc.write [msg.length].pack("S")
27
+ rc.write msg
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,26 @@
1
+ module Netz
2
+ class Catcher
3
+ attr_accessor :remote_clients, :command_channel
4
+
5
+ def initialize()
6
+ @remote_clients = []
7
+ end
8
+
9
+ def run
10
+ #thread per client?
11
+ @remote_clients.each do |rc|
12
+ Thread.new do
13
+ loop do
14
+ read_command(rc)
15
+ end
16
+ end
17
+ end
18
+ end
19
+
20
+ def read_command(remote_client)
21
+ length = remote_client.recvfrom(2)[0].unpack("S")[0]
22
+ cmd = CommandSerializer.deserialize(remote_client.recvfrom(length))
23
+ @command_channel << cmd
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,137 @@
1
+
2
+ module Netz
3
+ module ManagementCommands
4
+ PEER_CONNECT = 1
5
+ START = 2
6
+ end
7
+
8
+ class Client
9
+ include ManagementCommands
10
+ MANAGEMENT_PORT = 7370
11
+ INITIAL_PEER_PORT = 7374
12
+ def initialize
13
+ @port = INITIAL_PEER_PORT
14
+ @peers = SafeArray.new
15
+ Thread.new do
16
+ setup_management_port
17
+ end
18
+ end
19
+
20
+ def start_all
21
+ setup_with_siblings
22
+
23
+ @peers.each do |peer_socket|
24
+ to_send_address = peer_socket.peeraddr[3].split(":").last
25
+ puts "STARTING... #{to_send_address}"
26
+ peer_mng_socket = TCPSocket.new to_send_address, MANAGEMENT_PORT
27
+
28
+ peer_mng_socket << [START].pack("C")
29
+ peer_mng_socket.close
30
+ end
31
+ end
32
+
33
+ def add_peer(peer_socket)
34
+ @port += 1
35
+ Thread.new do
36
+ peer_server = TCPServer.open @port
37
+ puts "waiting for peer on per-peer port #{@port}"
38
+ peer = peer_server.accept
39
+ puts "accepted peer."
40
+ @peers.push(peer)
41
+ end
42
+ #push port, then ip strings
43
+ peer_socket << [@port].pack("I")
44
+ peer_socket << [@peers.size].pack("I")
45
+ @peers.each do |peer_socket|
46
+ # TODO will this always be peeraddr? or sometime addr depending on Server vs Socket?
47
+ to_send_address = peer_socket.peeraddr[3].split(":").last
48
+ peer_socket << [to_send_address.length].pack("I")
49
+ peer_socket << to_send_address
50
+ end
51
+ end
52
+
53
+ def setup_with_siblings
54
+ puts "setting up siblings"
55
+ @channel = Queue.new
56
+ broadcaster = Broadcaster.new
57
+ broadcaster.command_channel = @channel
58
+ broadcaster.remote_clients = @peers
59
+
60
+ catcher = Catcher.new
61
+ catcher.command_channel = @channel
62
+ catcher.remote_clients = @peers
63
+
64
+ catcher.run
65
+ broadcaster.run
66
+
67
+ @channel.push Command.new
68
+ end
69
+
70
+ def setup_management_port
71
+ puts "creating management port on #{MANAGEMENT_PORT}"
72
+ begin
73
+ server = TCPServer.open MANAGEMENT_PORT
74
+ @management_accept_thread = Thread.new do
75
+ begin
76
+ loop do
77
+ puts "management thread trying to accept..."
78
+ peer = server.accept
79
+ puts "YAY! peer connected!"
80
+
81
+ cmd = peer.recvfrom(1)[0].unpack("C")[0].to_i
82
+ case cmd
83
+ when PEER_CONNECT
84
+ puts "connection from peer #{peer.inspect}"
85
+ add_peer peer
86
+ when START
87
+ puts "got start"
88
+ setup_with_siblings
89
+ else
90
+ puts "unknown cmd"
91
+ p cmd
92
+ end
93
+
94
+ end
95
+ end
96
+ end
97
+ rescue Exception => ex
98
+ puts "client failed to open management port: #{ex}"
99
+ end
100
+
101
+ end
102
+
103
+ def connect_to_peer(ip, port)
104
+ puts "connecting to peer #{ip}:#{port}"
105
+ @peers << TCPSocket.new(ip, port)
106
+ end
107
+
108
+ def join(ip)
109
+ puts "trying to join #{ip}"
110
+ @joined_peer_ips ||= []
111
+ @joined_peer_ips << ip
112
+ peer_accept = TCPSocket.new ip, MANAGEMENT_PORT
113
+ peer_accept << [PEER_CONNECT].pack("C")
114
+
115
+ peer_ips = []
116
+ join_port = peer_accept.recvfrom(4)[0].unpack("I")[0]
117
+ puts "got join_port #{join_port}"
118
+ num_additional_peers = peer_accept.recvfrom(4)[0].unpack("I")[0]
119
+ puts "got num_additional_peers #{num_additional_peers}"
120
+ num_additional_peers.times do
121
+ puts "getting peer ip from stream"
122
+ ip_length = peer_accept.recvfrom(4)[0].unpack("I")
123
+ peer_ip = peer_accept.recvfrom(ip_length)[0].unpack("a")
124
+ peer_ips << peer_ip unless @joined_peer_ips.include? peer_ip
125
+ end
126
+
127
+ connect_to_peer ip, join_port
128
+
129
+ peer_accept.close
130
+
131
+ peer_ips.each do |pip|
132
+ join pip
133
+ end
134
+
135
+ end
136
+ end
137
+ end
@@ -0,0 +1,8 @@
1
+ module Netz
2
+ class Command
3
+ attr_writer :local
4
+ def local?
5
+ @local
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,13 @@
1
+ module Netz
2
+ module CommandSerializer
3
+ def serialize
4
+ self.to_s
5
+ end
6
+
7
+ def self.deserialize(cmd)
8
+ cmd = Command.new
9
+ #cmd.stuff = blah
10
+ cmd
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,43 @@
1
+ require 'thread'
2
+ module Netz
3
+ # a thread safe array class
4
+ class SafeArray
5
+ def initialize(items=[])
6
+ @items = items
7
+ @mutex = Mutex.new
8
+ end
9
+
10
+ def push(item)
11
+ @mutex.synchronize {
12
+ @items.push item
13
+ }
14
+ self
15
+ end
16
+ alias :<< :push
17
+
18
+ def delete(item)
19
+ @mutex.synchronize {
20
+ @items.delete item
21
+ }
22
+ end
23
+
24
+ def each(&block)
25
+ @mutex.synchronize {
26
+ @items.each(&block)
27
+ }
28
+ self
29
+ end
30
+
31
+ def empty?
32
+ @mutex.synchronize {
33
+ @items.empty?
34
+ }
35
+ end
36
+
37
+ def size
38
+ @mutex.synchronize {
39
+ @items.size
40
+ }
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,63 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{netz}
8
+ s.version = "0.0.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Shawn Anderson"]
12
+ s.date = %q{2010-10-27}
13
+ s.description = %q{P2P Networking library for us in games. }
14
+ s.email = %q{shawn42@gmail.com}
15
+ s.extra_rdoc_files = [
16
+ "README.rdoc"
17
+ ]
18
+ s.files = [
19
+ ".gitignore",
20
+ "README.rdoc",
21
+ "Rakefile",
22
+ "VERSION",
23
+ "lib/netz.rb",
24
+ "lib/netz/broadcaster.rb",
25
+ "lib/netz/catcher.rb",
26
+ "lib/netz/client.rb",
27
+ "lib/netz/command.rb",
28
+ "lib/netz/command_serializer.rb",
29
+ "lib/netz/safe_array.rb",
30
+ "netz.gemspec",
31
+ "script/run_client.rb",
32
+ "script/run_lobby.rb"
33
+ ]
34
+ s.homepage = %q{http://shawn42.github.com/netz}
35
+ s.rdoc_options = ["--charset=UTF-8"]
36
+ s.require_paths = ["lib"]
37
+ s.rubyforge_project = %q{netz}
38
+ s.rubygems_version = %q{1.3.7}
39
+ s.summary = %q{Networking library for use in games.}
40
+
41
+ if s.respond_to? :specification_version then
42
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
43
+ s.specification_version = 3
44
+
45
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
46
+ s.add_development_dependency(%q<rspec>, [">= 0"])
47
+ s.add_development_dependency(%q<jeweler>, [">= 0"])
48
+ s.add_runtime_dependency(%q<gosu>, [">= 0"])
49
+ s.add_runtime_dependency(%q<bundler>, [">= 0"])
50
+ else
51
+ s.add_dependency(%q<rspec>, [">= 0"])
52
+ s.add_dependency(%q<jeweler>, [">= 0"])
53
+ s.add_dependency(%q<gosu>, [">= 0"])
54
+ s.add_dependency(%q<bundler>, [">= 0"])
55
+ end
56
+ else
57
+ s.add_dependency(%q<rspec>, [">= 0"])
58
+ s.add_dependency(%q<jeweler>, [">= 0"])
59
+ s.add_dependency(%q<gosu>, [">= 0"])
60
+ s.add_dependency(%q<bundler>, [">= 0"])
61
+ end
62
+ end
63
+
@@ -0,0 +1,7 @@
1
+ require 'netz'
2
+
3
+ client = Netz::Client.new
4
+ client.join ARGV.pop
5
+
6
+ puts "client is waiting..."
7
+ gets
@@ -0,0 +1,9 @@
1
+ require 'netz'
2
+
3
+ c = Netz::Client.new
4
+ puts "waiting..."
5
+ gets
6
+ c.start_all
7
+
8
+ puts "DONE.. please continue"
9
+ gets
metadata ADDED
@@ -0,0 +1,135 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: netz
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Shawn Anderson
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-10-27 00:00:00 -04:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: rspec
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ type: :development
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: jeweler
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ hash: 3
44
+ segments:
45
+ - 0
46
+ version: "0"
47
+ type: :development
48
+ version_requirements: *id002
49
+ - !ruby/object:Gem::Dependency
50
+ name: gosu
51
+ prerelease: false
52
+ requirement: &id003 !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ hash: 3
58
+ segments:
59
+ - 0
60
+ version: "0"
61
+ type: :runtime
62
+ version_requirements: *id003
63
+ - !ruby/object:Gem::Dependency
64
+ name: bundler
65
+ prerelease: false
66
+ requirement: &id004 !ruby/object:Gem::Requirement
67
+ none: false
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ hash: 3
72
+ segments:
73
+ - 0
74
+ version: "0"
75
+ type: :runtime
76
+ version_requirements: *id004
77
+ description: "P2P Networking library for us in games. "
78
+ email: shawn42@gmail.com
79
+ executables: []
80
+
81
+ extensions: []
82
+
83
+ extra_rdoc_files:
84
+ - README.rdoc
85
+ files:
86
+ - .gitignore
87
+ - README.rdoc
88
+ - Rakefile
89
+ - VERSION
90
+ - lib/netz.rb
91
+ - lib/netz/broadcaster.rb
92
+ - lib/netz/catcher.rb
93
+ - lib/netz/client.rb
94
+ - lib/netz/command.rb
95
+ - lib/netz/command_serializer.rb
96
+ - lib/netz/safe_array.rb
97
+ - netz.gemspec
98
+ - script/run_client.rb
99
+ - script/run_lobby.rb
100
+ has_rdoc: true
101
+ homepage: http://shawn42.github.com/netz
102
+ licenses: []
103
+
104
+ post_install_message:
105
+ rdoc_options:
106
+ - --charset=UTF-8
107
+ require_paths:
108
+ - lib
109
+ required_ruby_version: !ruby/object:Gem::Requirement
110
+ none: false
111
+ requirements:
112
+ - - ">="
113
+ - !ruby/object:Gem::Version
114
+ hash: 3
115
+ segments:
116
+ - 0
117
+ version: "0"
118
+ required_rubygems_version: !ruby/object:Gem::Requirement
119
+ none: false
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ hash: 3
124
+ segments:
125
+ - 0
126
+ version: "0"
127
+ requirements: []
128
+
129
+ rubyforge_project: netz
130
+ rubygems_version: 1.3.7
131
+ signing_key:
132
+ specification_version: 3
133
+ summary: Networking library for use in games.
134
+ test_files: []
135
+