gamefic-mud 0.0.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 1a8fbce2090194a364d012ad04c933a9c1ff572f
4
- data.tar.gz: 31c1ff56b98dd54c820092872fb379f92224c6e8
2
+ SHA256:
3
+ metadata.gz: ff2aa9c86a961ebb613299ee247dc201b473c7659c4a035546e4143f0a35b863
4
+ data.tar.gz: 5abc56417d93af1c3dea919e90614672eb4f920024971f52235487399194f2d0
5
5
  SHA512:
6
- metadata.gz: 8b4ff2794d6b3aeb5e52c700635c7c72efee2e5f01f3d57ef0e3b12e3b76ea8734a0c532afd2b61d833c3b0647d5f8aa563e2f8951f4d5aa261b705b7fbfaf47
7
- data.tar.gz: 2307f17548a756283f15571eab5c04da03e268ce4d86df59fd74b65a029fdd02bb858b8dc3b15f804a5988249265bf795fefc39de162f347a971a9a0001ef62a
6
+ metadata.gz: cb8514110747d8d4d8df20c48e0c6685bc2a6b8961dbdc47c0439fd668c0a8dd75f55eb01e70a847681cc667a01c46ca75f40117f5483e2fa1e14dd3028a0ccd
7
+ data.tar.gz: b5ecc5b4e032a94298c17d9e198883182be82881ecaa5001d7ab6aaa730301b75671347437f813e551c94a7b525e10fa7fdf432374088dda1c2bda020a9f6944
data/lib/gamefic-mud.rb CHANGED
@@ -1,8 +1,9 @@
1
- module Gamefic
2
-
3
- module Mud
4
- autoload :Engine, 'gamefic-mud/engine'
5
- autoload :User, 'gamefic-mud/user'
6
- end
7
-
8
- end
1
+ require 'gamefic'
2
+
3
+ module Gamefic
4
+ module Mud
5
+ autoload :Adapter, 'gamefic-mud/adapter'
6
+ autoload :Engine, 'gamefic-mud/engine'
7
+ autoload :State, 'gamefic-mud/state'
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module Gamefic
2
+ module Mud
3
+ module Adapter
4
+ autoload :Common, 'gamefic-mud/adapter/common'
5
+ autoload :Tcp, 'gamefic-mud/adapter/tcp'
6
+ autoload :Websocket, 'gamefic-mud/adapter/websocket'
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,60 @@
1
+ module Gamefic
2
+ module Mud
3
+ module Adapter
4
+ # Common attributes and methods of client adapters.
5
+ #
6
+ module Common
7
+ # @return [Plot]
8
+ attr_accessor :plot
9
+
10
+ # @return [Actor]
11
+ attr_accessor :character
12
+
13
+ # @return [State::Base]
14
+ attr_reader :state
15
+
16
+ # @param state [Class<State::Base>]
17
+ # @return [void]
18
+ def start state
19
+ @state = state.new(self)
20
+ @state.start
21
+ end
22
+
23
+ def session
24
+ @session ||= {}
25
+ end
26
+
27
+ def [] key
28
+ session[key]
29
+ end
30
+
31
+ def []= key, value
32
+ session[key] = value
33
+ end
34
+
35
+ # @!method send_raw(data)
36
+ # Send raw data to the client outside of the game.
37
+ # Normally, game-related data is sent through the character,
38
+ # usually via `character#tell` or `character#stream`. `#raw_data`
39
+ # allows the engine to communicate with the client outside of the
40
+ # game proper, e.g., to display a login prompt.
41
+ #
42
+ # Adapters should implement this method.
43
+ #
44
+ # @abstract
45
+ # @param data [String] The message text
46
+ # @return [void]
47
+
48
+ # @!method update(output)
49
+ # Send a game update to the client. The engine uses this method to
50
+ # broadcast messages and provide data about the current game state.
51
+ #
52
+ # Adapters should implement this method.
53
+ #
54
+ # @abstract
55
+ # @param output [Hash]
56
+ # @return [void]
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,61 @@
1
+ require 'html_to_ansi'
2
+ require 'socket'
3
+
4
+ module Gamefic
5
+ module Mud
6
+ module Adapter
7
+ # The TCP client adapter module.
8
+ #
9
+ module Tcp
10
+ include Common
11
+
12
+ # @return [String]
13
+ attr_reader :ip_addr
14
+
15
+ # @return [Integer]
16
+ attr_reader :port
17
+
18
+ def post_init
19
+ port, ip = Socket.unpack_sockaddr_in(get_peername)
20
+ @port = port
21
+ @ip_addr = ip
22
+ puts "Connection received from #{ip}:#{port}"
23
+ end
24
+
25
+ def receive_data data
26
+ state.process data
27
+ end
28
+
29
+ def update output
30
+ # TCP connections are assumed to be terminal clients. Convert messages and options into
31
+ # an HTML block and convert it to ANSI text.
32
+ text = output[:messages]
33
+ unless output[:options].nil?
34
+ list = '<ol>'
35
+ state[:options].each do |o|
36
+ list += "<li>#{o}</li>"
37
+ end
38
+ list += "</ol>"
39
+ text += list
40
+ end
41
+ # @todo The line endings should probably be a function of HtmlToAnsi.
42
+ send_data HtmlToAnsi.convert(text).gsub(/\n/, "\r\n")
43
+ end
44
+
45
+ def send_raw data
46
+ send_data data
47
+ end
48
+
49
+ def receive_data data
50
+ state.process data.to_s.strip
51
+ end
52
+
53
+ def unbind
54
+ puts "Disconnecting from #{ip_addr}:#{port}"
55
+ # @todo Right way to remove player from game?
56
+ plot.destroy character unless character.nil?
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,30 @@
1
+ require 'json'
2
+
3
+ module Gamefic
4
+ module Mud
5
+ module Adapter
6
+ # The WebSocket client adapter module.
7
+ #
8
+ module Websocket
9
+ include Common
10
+
11
+ # @param output [Hash]
12
+ # @return [void]
13
+ def update output
14
+ # Websocket connections are assumed to be rich clients. Send them
15
+ # the entire output hash and let them determine how to render the
16
+ # data.
17
+ send output.to_json
18
+ end
19
+
20
+ # @param data [String]
21
+ # @return [void]
22
+ def send_raw data
23
+ # Convert raw text to a hash with a `messages` key so the WebSocket
24
+ # client can rely on a single standard for incoming data.
25
+ update({messages: data})
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -1,146 +1,129 @@
1
- require 'websocket-eventmachine-server'
2
-
3
- module Gamefic
4
-
5
- class Mud::Engine < Gamefic::Engine::Base
6
- def post_initialize
7
- @web_connections = {}
8
- @accepts = []
9
- end
10
-
11
- def will_accept type: :tcpsocket, host: '0.0.0.0', port: 4342
12
- @accepts.push({ type: type, host: host, port: port })
13
- end
14
-
15
- def will_accept_tcpsocket host: '0.0.0.0', port: 4342
16
- will_accept type: :tcpsocket, host: host, port: port
17
- end
18
-
19
- def will_accept_websocket host: '0.0.0.0', port: 4343
20
- will_accept type: :websocket, host: host, port: port
21
- end
22
-
23
- def run
24
- EM.epoll
25
- EM.run do
26
- trap("TERM") { stop }
27
- trap("INT") { stop }
28
-
29
- if @accepts.empty?
30
- will_accept
31
- end
32
- @accepts.each { |a|
33
- if a[:type] == :websocket
34
- start_websocket host: a[:host], port: a[:port]
35
- else
36
- start_tcpsocket host: a[:host], port: a[:port]
37
- end
38
- }
39
-
40
- EventMachine.add_periodic_timer 1 do
41
- plot.ready
42
- plot.update
43
- plot.players.each { |p|
44
- data = p.user.flush
45
- if data != ''
46
- p.user.update data
47
- p.user.prompt p.prompt
48
- end
49
- }
50
- end
51
- end
52
-
53
- end
54
-
55
- def stop
56
- puts "Terminating WebSocket Server"
57
- EventMachine.stop
58
- end
59
-
60
- private
61
-
62
- def start_websocket host:, port:
63
- ::WebSocket::EventMachine::Server.start(host: host, port: port) do |ws|
64
-
65
- ws.onopen do
66
- puts "Client connected"
67
- user = Gamefic::Mud::User::WebSocket.new(ws, self)
68
- user.start Mud::User::State::Login
69
- @web_connections[ws] = user
70
- end
71
-
72
- ws.onmessage do |msg, type|
73
- @web_connections[ws].process msg
74
- end
75
-
76
- ws.onclose do
77
- puts "Client disconnected"
78
- plot.destroy @web_connections[ws].character unless @web_connections[ws].character.nil?
79
- @web_connections.delete ws
80
- end
81
-
82
- ws.onerror do |e|
83
- puts "Error: #{e}"
84
- end
85
-
86
- ws.onping do |msg|
87
- puts "Received ping: #{msg}"
88
- end
89
-
90
- ws.onpong do |msg|
91
- puts "Received pong: #{msg}"
92
- end
93
-
94
- end
95
-
96
- puts "WebSocket server started on #{host}:#{port}"
97
- end
98
-
99
- module TcpHandler
100
- attr_accessor :plot
101
- attr_accessor :user
102
- attr_reader :ip_addr
103
- attr_reader :port
104
-
105
- def post_init
106
- port, ip = Socket.unpack_sockaddr_in(get_peername)
107
- @port = port
108
- @ip_addr = ip
109
- puts "Connection received from #{ip}:#{port}"
110
- end
111
-
112
- def receive_data data
113
- # HACK Convert to UTF-8 and close connection on errors
114
- conv = ''
115
- data.each_byte { |b|
116
- c = b.chr.encode('UTF-8')
117
- if c.valid_encoding?
118
- conv += c
119
- else
120
- conv += '?'
121
- end
122
- }
123
- conv.strip!
124
- user.process conv
125
- rescue Encoding::UndefinedConversionError
126
- puts 'Throwing away garbage'
127
- close_connection
128
- end
129
- def unbind
130
- puts "Disconnecting from #{ip_addr}:#{port}"
131
- plot.destroy user.character unless user.character.nil?
132
- end
133
- end
134
-
135
- def start_tcpsocket host:, port:
136
- EventMachine.start_server host, port, TcpHandler do |conn|
137
- conn.plot = plot
138
- conn.user = Gamefic::Mud::User::TcpSocket.new(conn, self)
139
- conn.user.start Mud::User::State::Login
140
- end
141
-
142
- puts "Telnet server started on #{host}:#{port}"
143
- end
144
- end
145
-
146
- end
1
+ require 'eventmachine'
2
+ require 'em-websocket'
3
+
4
+ module Gamefic
5
+ module Mud
6
+ # The MUD server engine. Responsible for handling client connections and
7
+ # updating the game state.
8
+ #
9
+ class Engine
10
+ # @return [Plot]
11
+ attr_reader :plot
12
+
13
+ # @param plot [Plot] The game plot
14
+ # @param start [Class<State::Base>] The initial state for new connections
15
+ # @param interval [Numeric] The number of seconds between updates
16
+ def initialize plot, start: State::Guest, interval: 1
17
+ @plot = plot
18
+ @start = start
19
+ @interval = interval
20
+ @web_connections = {}
21
+ @accepts = []
22
+ @connections = []
23
+ end
24
+
25
+ # Tell the engine to run a TCP or WebSocket server.
26
+ #
27
+ # @param type [Symbol] :tcpsocket or :websocket
28
+ # @param host [String] The host name
29
+ # @param port [Integer] The port number
30
+ # @return [void]
31
+ def will_accept type: :tcpsocket, host: '0.0.0.0', port: 4342
32
+ @accepts.push({ type: type, host: host, port: port })
33
+ end
34
+
35
+ # Tell the engine to run a TCP server.
36
+ #
37
+ # @param host [String] The host name
38
+ # @param port [Integer] The port number
39
+ # @return [void]
40
+ def will_accept_tcpsocket host: '0.0.0.0', port: 4342
41
+ will_accept type: :tcpsocket, host: host, port: port
42
+ end
43
+
44
+ # Tell the engine to run a WebSocket server.
45
+ #
46
+ # @param host [String] The host name
47
+ # @param port [Integer] The port number
48
+ # @return [void]
49
+ def will_accept_websocket host: '0.0.0.0', port: 4343
50
+ will_accept type: :websocket, host: host, port: port
51
+ end
52
+
53
+ # Start the engine.
54
+ #
55
+ # @return [void]
56
+ def run
57
+ EM.epoll
58
+ EM.run do
59
+ trap("TERM") { stop }
60
+ trap("INT") { stop }
61
+
62
+ # Start a default TCP server if none are configured
63
+ will_accept if @accepts.empty?
64
+
65
+ @accepts.each do |a|
66
+ if a[:type] == :websocket
67
+ start_websocket host: a[:host], port: a[:port]
68
+ else
69
+ start_tcpsocket host: a[:host], port: a[:port]
70
+ end
71
+ end
72
+
73
+ EventMachine.add_periodic_timer @interval do
74
+ plot.update
75
+ plot.ready
76
+ @connections.each do |conn|
77
+ next unless conn.character
78
+ conn.update conn.character.output
79
+ end
80
+ end
81
+ end
82
+ end
83
+
84
+ def self.start plot, **options
85
+ engine = new(plot, **options)
86
+ yield(engine) if block_given?
87
+ engine.run
88
+ end
89
+
90
+ # Stop the engine.
91
+ #
92
+ # @return [void]
93
+ def stop
94
+ puts "Terminating server"
95
+ EventMachine.stop
96
+ end
97
+
98
+ private
99
+
100
+ def start_websocket host:, port:
101
+ EM::WebSocket.run(host: host, port: port) do |ws|
102
+ ws.onopen do |_handshake|
103
+ ws.extend Adapter::Websocket
104
+ ws.plot = plot
105
+ ws.start @start
106
+ @connections.push ws
107
+ end
108
+
109
+ # WebSocket messages are handled here because using `receive_data` in
110
+ # the adapter raises character encoding errors.
111
+ ws.onmessage do |msg|
112
+ ws.state.process msg.to_s.strip
113
+ end
114
+ end
115
+ puts "WebSocket server started on #{host}:#{port}"
116
+ end
117
+
118
+ def start_tcpsocket host:, port:
119
+ EventMachine.start_server host, port, Adapter::Tcp do |conn|
120
+ conn.plot = plot
121
+ conn.start @start
122
+ @connections.push conn
123
+ end
124
+
125
+ puts "Telnet server started on #{host}:#{port}"
126
+ end
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,9 @@
1
+ module Gamefic
2
+ module Mud
3
+ module State
4
+ autoload :Base, 'gamefic-mud/state/base'
5
+ autoload :Guest, 'gamefic-mud/state/guest'
6
+ autoload :Play, 'gamefic-mud/state/play'
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,34 @@
1
+ module Gamefic
2
+ module Mud
3
+ module State
4
+ # An abstract class for handling client states.
5
+ #
6
+ class Base
7
+ # @return [Adapter::Common]
8
+ attr_reader :adapter
9
+
10
+ # @param adapter [Adapter::Common]
11
+ def initialize adapter
12
+ @adapter = adapter
13
+ end
14
+
15
+ # Called when a client's state changes.
16
+ # Subclasses should implement this method.
17
+ #
18
+ # @return [void]
19
+ def start
20
+ puts "User started #{self.class}"
21
+ end
22
+
23
+ # Called when a message is received from a client.
24
+ # Subclasses should implement this method.
25
+ #
26
+ # @param message [String]
27
+ # @return [void]
28
+ def process message
29
+ puts "User sent #{message} in #{self.class}"
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,28 @@
1
+ module Gamefic
2
+ module Mud
3
+ module State
4
+ # A simple introductory state that creates a character with a name
5
+ # provided by the user. MUDs in production should implement a more
6
+ # robust version of authentication, but this is sufficient for testing
7
+ # and development.
8
+ #
9
+ class Guest < Base
10
+ def start
11
+ adapter.send_raw 'Enter your name: '
12
+ end
13
+
14
+ def process message
15
+ if message.strip.empty?
16
+ adapter.send_raw "Blank names are not allowed.\r\n"
17
+ start
18
+ else
19
+ character = adapter.plot.make_player_character
20
+ character.name = message.strip
21
+ adapter.character = character
22
+ adapter.start Mud::State::Play
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,22 @@
1
+ module Gamefic
2
+ module Mud
3
+ module State
4
+ # The typical gameplay handler. This state processes client messages as
5
+ # commands to be executed by the player's character.
6
+ #
7
+ class Play < Base
8
+ def start
9
+ adapter.plot.introduce adapter.character
10
+ # Since the game is already running when the player connects, the
11
+ # plot update flushes messages received in the introduction. We're
12
+ # working around the problem by sending them here.
13
+ adapter.update({ messages: adapter.character.messages })
14
+ end
15
+
16
+ def process message
17
+ adapter.character.queue.push message unless message == ''
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -1,5 +1,5 @@
1
- module Gamefic
2
- module Mud
3
- VERSION = '0.0.1'
4
- end
5
- end
1
+ module Gamefic
2
+ module Mud
3
+ VERSION = '1.0.0'
4
+ end
5
+ end
metadata CHANGED
@@ -1,43 +1,105 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gamefic-mud
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Fred Snyder
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-02-06 00:00:00.000000000 Z
11
+ date: 2021-07-10 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: em-websocket
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.5'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.5'
27
+ - !ruby/object:Gem::Dependency
28
+ name: eventmachine
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.2'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.2'
13
41
  - !ruby/object:Gem::Dependency
14
42
  name: gamefic
15
43
  requirement: !ruby/object:Gem::Requirement
16
44
  requirements:
17
- - - ">="
45
+ - - "~>"
18
46
  - !ruby/object:Gem::Version
19
- version: '0'
47
+ version: '2.1'
20
48
  type: :runtime
21
49
  prerelease: false
22
50
  version_requirements: !ruby/object:Gem::Requirement
23
51
  requirements:
24
- - - ">="
52
+ - - "~>"
25
53
  - !ruby/object:Gem::Version
26
- version: '0'
54
+ version: '2.1'
27
55
  - !ruby/object:Gem::Dependency
28
- name: websocket-eventmachine-server
56
+ name: html_to_ansi
29
57
  requirement: !ruby/object:Gem::Requirement
30
58
  requirements:
31
59
  - - "~>"
32
60
  - !ruby/object:Gem::Version
33
- version: 1.0.1
61
+ version: '0.1'
34
62
  type: :runtime
35
63
  prerelease: false
36
64
  version_requirements: !ruby/object:Gem::Requirement
37
65
  requirements:
38
66
  - - "~>"
39
67
  - !ruby/object:Gem::Version
40
- version: 1.0.1
68
+ version: '0.1'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '3.5'
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: 3.5.0
79
+ type: :development
80
+ prerelease: false
81
+ version_requirements: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - "~>"
84
+ - !ruby/object:Gem::Version
85
+ version: '3.5'
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: 3.5.0
89
+ - !ruby/object:Gem::Dependency
90
+ name: simplecov
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: '0.14'
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: '0.14'
41
103
  description: An engine for running multiplayer games with Gamefic
42
104
  email: fsnyder@gamefic.com
43
105
  executables: []
@@ -45,21 +107,21 @@ extensions: []
45
107
  extra_rdoc_files: []
46
108
  files:
47
109
  - lib/gamefic-mud.rb
110
+ - lib/gamefic-mud/adapter.rb
111
+ - lib/gamefic-mud/adapter/common.rb
112
+ - lib/gamefic-mud/adapter/tcp.rb
113
+ - lib/gamefic-mud/adapter/websocket.rb
48
114
  - lib/gamefic-mud/engine.rb
49
- - lib/gamefic-mud/user.rb
50
- - lib/gamefic-mud/user/base.rb
51
- - lib/gamefic-mud/user/state.rb
52
- - lib/gamefic-mud/user/state/base.rb
53
- - lib/gamefic-mud/user/state/login.rb
54
- - lib/gamefic-mud/user/state/play.rb
55
- - lib/gamefic-mud/user/tcpsocket.rb
56
- - lib/gamefic-mud/user/websocket.rb
115
+ - lib/gamefic-mud/state.rb
116
+ - lib/gamefic-mud/state/base.rb
117
+ - lib/gamefic-mud/state/guest.rb
118
+ - lib/gamefic-mud/state/play.rb
57
119
  - lib/gamefic-mud/version.rb
58
120
  homepage: http://gamefic.com
59
121
  licenses:
60
122
  - MIT
61
123
  metadata: {}
62
- post_install_message:
124
+ post_install_message:
63
125
  rdoc_options: []
64
126
  require_paths:
65
127
  - lib
@@ -74,9 +136,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
74
136
  - !ruby/object:Gem::Version
75
137
  version: '0'
76
138
  requirements: []
77
- rubyforge_project:
78
- rubygems_version: 2.5.1
79
- signing_key:
139
+ rubygems_version: 3.1.6
140
+ signing_key:
80
141
  specification_version: 4
81
142
  summary: Gamefic MUD
82
143
  test_files: []
@@ -1,10 +0,0 @@
1
- module Gamefic
2
-
3
- module Mud::User
4
- autoload :Base, 'gamefic-mud/user/base'
5
- autoload :State, 'gamefic-mud/user/state'
6
- autoload :WebSocket, 'gamefic-mud/user/websocket'
7
- autoload :TcpSocket, 'gamefic-mud/user/tcpsocket'
8
- end
9
-
10
- end
@@ -1,32 +0,0 @@
1
- module Gamefic
2
-
3
- class Mud::User::Base < Gamefic::User::Base
4
- attr_accessor :character
5
- attr_reader :engine
6
-
7
- def initialize connection, engine
8
- @connection = connection
9
- @engine = engine
10
- @state = Mud::User::State::Base.new(self)
11
- end
12
-
13
- def start user_state
14
- @state = user_state.new(self)
15
- @state.start
16
- end
17
-
18
- def process message
19
- @state.process message
20
- end
21
-
22
- def update data
23
- end
24
-
25
- def transmit data
26
- end
27
-
28
- def prompt text
29
- end
30
- end
31
-
32
- end
@@ -1,9 +0,0 @@
1
- module Gamefic
2
-
3
- module Mud::User::State
4
- autoload :Base, 'gamefic-mud/user/state/base'
5
- autoload :Login, 'gamefic-mud/user/state/login'
6
- autoload :Play, 'gamefic-mud/user/state/play'
7
- end
8
-
9
- end
@@ -1,23 +0,0 @@
1
- module Gamefic
2
-
3
- module Mud::User::State
4
-
5
- class Base
6
- attr_reader :user
7
-
8
- def initialize user
9
- @user ||= user
10
- end
11
-
12
- def start
13
- puts "User started #{self.class}"
14
- end
15
-
16
- def process message
17
- puts "User sent #{message} in #{self.class}"
18
- end
19
-
20
- end
21
-
22
- end
23
- end
@@ -1,21 +0,0 @@
1
- module Gamefic
2
-
3
- module Mud::User::State
4
-
5
- class Login < Base
6
-
7
- def start
8
- user.prompt 'Enter your name:'
9
- end
10
-
11
- def process message
12
- character = user.engine.plot.make Character, name: message, description: "#{message} is your name."
13
- character.connect user
14
- user.character = character
15
- user.transmit "Welcome, #{message}."
16
- user.start Mud::User::State::Play
17
- end
18
- end
19
-
20
- end
21
- end
@@ -1,13 +0,0 @@
1
- module Gamefic
2
-
3
- class Mud::User::State::Play < Mud::User::State::Base
4
- def start
5
- user.engine.plot.introduce user.character
6
- end
7
-
8
- def process message
9
- user.character.queue.push message unless message == ''
10
- end
11
- end
12
-
13
- end
@@ -1,19 +0,0 @@
1
- require 'gamefic/text'
2
-
3
- module Gamefic
4
-
5
- class Mud::User::TcpSocket < Mud::User::Base
6
- def update data
7
- transmit "\n" + Gamefic::Text::Html::Conversions.html_to_ansi(data)
8
- end
9
-
10
- def transmit data
11
- @connection.send_data data
12
- end
13
-
14
- def prompt text
15
- transmit "\n#{text} "
16
- end
17
- end
18
-
19
- end
@@ -1,17 +0,0 @@
1
- module Gamefic
2
-
3
- class Mud::User::WebSocket < Mud::User::Base
4
- def update data
5
- transmit data
6
- end
7
-
8
- def transmit data
9
- @connection.send data
10
- end
11
-
12
- def prompt text
13
- transmit "<label class=\"prompt\">#{text}</label>"
14
- end
15
- end
16
-
17
- end