game_machine 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (273) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +4 -0
  3. data/Gemfile.lock +72 -0
  4. data/Rakefile +38 -0
  5. data/bin/game_machine +79 -0
  6. data/config/cluster.conf +65 -0
  7. data/config/config.example.yml +93 -0
  8. data/config/game_messages.proto +45 -0
  9. data/config/messages.proto +339 -0
  10. data/config/regions.example.yml +9 -0
  11. data/config/standalone.conf +36 -0
  12. data/db/do_not_delete +0 -0
  13. data/game_machine.gemspec +38 -0
  14. data/games/example/boot.rb +6 -0
  15. data/games/example/data/game_data.yml +13 -0
  16. data/games/example/lib/aggressive_npc.rb +176 -0
  17. data/games/example/lib/authentication_handler.rb +69 -0
  18. data/games/example/lib/chatbot.rb +61 -0
  19. data/games/example/lib/combat_controller.rb +145 -0
  20. data/games/example/lib/example_controller.rb +21 -0
  21. data/games/example/lib/game.rb +85 -0
  22. data/games/example/lib/models/attack.rb +9 -0
  23. data/games/example/lib/models/combat_update.rb +11 -0
  24. data/games/example/lib/models/player_command.rb +7 -0
  25. data/games/example/lib/models/user.rb +11 -0
  26. data/games/example/lib/models/vitals.rb +17 -0
  27. data/games/example/lib/npc.rb +111 -0
  28. data/games/example/lib/npc_group.rb +42 -0
  29. data/games/example/lib/npc_movement.rb +116 -0
  30. data/games/example/lib/player_manager.rb +58 -0
  31. data/games/example/lib/player_register.rb +80 -0
  32. data/games/example/lib/tracking_handler.rb +17 -0
  33. data/games/example/lib/zone_manager.rb +57 -0
  34. data/games/preload.rb +8 -0
  35. data/integration_tests/basic_spec.rb +68 -0
  36. data/integration_tests/bot_spec.rb +18 -0
  37. data/integration_tests/chat_spec.rb +45 -0
  38. data/integration_tests/distributed_spec.rb +34 -0
  39. data/integration_tests/entity_tracking_spec.rb +48 -0
  40. data/integration_tests/mono_spec.rb +16 -0
  41. data/integration_tests/objectdb_spec.rb +55 -0
  42. data/integration_tests/tcp_client_spec.rb +71 -0
  43. data/integration_tests/udp_client_spec.rb +61 -0
  44. data/integration_tests/udp_spec.rb +20 -0
  45. data/integration_tests/udt_client_spec.rb +23 -0
  46. data/integration_tests/udt_spec.rb +31 -0
  47. data/java/.gitignore +1 -0
  48. data/java/build.gradle +93 -0
  49. data/java/component.erb +396 -0
  50. data/java/gradle.properties +6 -0
  51. data/java/gradle/wrapper/gradle-wrapper.jar +0 -0
  52. data/java/gradle/wrapper/gradle-wrapper.properties +6 -0
  53. data/java/gradlew +164 -0
  54. data/java/gradlew.bat +90 -0
  55. data/java/local_lib/protostuff-compiler-1.0.7-jarjar.jar +0 -0
  56. data/java/settings.gradle +2 -0
  57. data/java/src/main/java/com/game_machine/core/ActorFactory.java +25 -0
  58. data/java/src/main/java/com/game_machine/core/ActorUtil.java +39 -0
  59. data/java/src/main/java/com/game_machine/core/CommandProxy.java +9 -0
  60. data/java/src/main/java/com/game_machine/core/EntitySerializer.java +66 -0
  61. data/java/src/main/java/com/game_machine/core/EventStreamHandler.java +43 -0
  62. data/java/src/main/java/com/game_machine/core/GameMachineLoader.java +25 -0
  63. data/java/src/main/java/com/game_machine/core/Grid.java +195 -0
  64. data/java/src/main/java/com/game_machine/core/GridValue.java +30 -0
  65. data/java/src/main/java/com/game_machine/core/IActorFactory.java +7 -0
  66. data/java/src/main/java/com/game_machine/core/NetMessage.java +28 -0
  67. data/java/src/main/java/com/game_machine/core/UdpServer.java +97 -0
  68. data/java/src/main/java/com/game_machine/core/UdpServerHandler.java +90 -0
  69. data/java/src/main/resources/game_machine.java.stg +738 -0
  70. data/java/src/main/resources/logback.xml +14 -0
  71. data/java/src/main/resources/logging.properties +3 -0
  72. data/java/src/main/resources/protostuff.properties +7 -0
  73. data/lib/game_machine.rb +85 -0
  74. data/lib/game_machine/actor.rb +7 -0
  75. data/lib/game_machine/actor/base.rb +184 -0
  76. data/lib/game_machine/actor/builder.rb +108 -0
  77. data/lib/game_machine/actor/development.rb +31 -0
  78. data/lib/game_machine/actor/factory.rb +35 -0
  79. data/lib/game_machine/actor/mono_actor.rb +89 -0
  80. data/lib/game_machine/actor/ref.rb +81 -0
  81. data/lib/game_machine/actor/reloadable.rb +98 -0
  82. data/lib/game_machine/actor/system.rb +32 -0
  83. data/lib/game_machine/akka.rb +98 -0
  84. data/lib/game_machine/app_config.rb +49 -0
  85. data/lib/game_machine/application.rb +181 -0
  86. data/lib/game_machine/auth_handlers/base.rb +21 -0
  87. data/lib/game_machine/auth_handlers/public.rb +34 -0
  88. data/lib/game_machine/bot/chat.rb +66 -0
  89. data/lib/game_machine/bot/client.rb +54 -0
  90. data/lib/game_machine/client_manager.rb +204 -0
  91. data/lib/game_machine/clients.rb +4 -0
  92. data/lib/game_machine/clients/client.rb +45 -0
  93. data/lib/game_machine/clients/tcp_client.rb +25 -0
  94. data/lib/game_machine/clients/test_client.rb +151 -0
  95. data/lib/game_machine/clients/udp_client.rb +25 -0
  96. data/lib/game_machine/clients/udt_client.rb +34 -0
  97. data/lib/game_machine/cluster_monitor.rb +115 -0
  98. data/lib/game_machine/commands.rb +23 -0
  99. data/lib/game_machine/commands/base.rb +21 -0
  100. data/lib/game_machine/commands/chat_commands.rb +88 -0
  101. data/lib/game_machine/commands/datastore_commands.rb +60 -0
  102. data/lib/game_machine/commands/grid_commands.rb +35 -0
  103. data/lib/game_machine/commands/message_helper.rb +25 -0
  104. data/lib/game_machine/commands/misc_commands.rb +29 -0
  105. data/lib/game_machine/commands/navigation_commands.rb +24 -0
  106. data/lib/game_machine/commands/player_commands.rb +28 -0
  107. data/lib/game_machine/commands/proxy.rb +16 -0
  108. data/lib/game_machine/console.rb +3 -0
  109. data/lib/game_machine/console/build.rb +74 -0
  110. data/lib/game_machine/console/install.rb +92 -0
  111. data/lib/game_machine/console/server.rb +120 -0
  112. data/lib/game_machine/data_store.rb +52 -0
  113. data/lib/game_machine/data_stores/couchbase.rb +18 -0
  114. data/lib/game_machine/data_stores/mapdb.rb +49 -0
  115. data/lib/game_machine/data_stores/memory.rb +35 -0
  116. data/lib/game_machine/data_stores/redis.rb +46 -0
  117. data/lib/game_machine/endpoints.rb +6 -0
  118. data/lib/game_machine/endpoints/mono_gateway.rb +87 -0
  119. data/lib/game_machine/endpoints/tcp.rb +51 -0
  120. data/lib/game_machine/endpoints/tcp_handler.rb +75 -0
  121. data/lib/game_machine/endpoints/udp.rb +88 -0
  122. data/lib/game_machine/endpoints/udp_incoming.rb +113 -0
  123. data/lib/game_machine/endpoints/udp_outgoing.rb +46 -0
  124. data/lib/game_machine/game_loader.rb +46 -0
  125. data/lib/game_machine/game_systems.rb +14 -0
  126. data/lib/game_machine/game_systems/agents/controller.rb +118 -0
  127. data/lib/game_machine/game_systems/chat.rb +256 -0
  128. data/lib/game_machine/game_systems/chat_manager.rb +108 -0
  129. data/lib/game_machine/game_systems/chat_topic.rb +36 -0
  130. data/lib/game_machine/game_systems/devnull.rb +13 -0
  131. data/lib/game_machine/game_systems/entity_loader.rb +12 -0
  132. data/lib/game_machine/game_systems/entity_tracking.rb +133 -0
  133. data/lib/game_machine/game_systems/local_echo.rb +16 -0
  134. data/lib/game_machine/game_systems/objectdb_proxy.rb +61 -0
  135. data/lib/game_machine/game_systems/private_chat.rb +20 -0
  136. data/lib/game_machine/game_systems/region_manager.rb +91 -0
  137. data/lib/game_machine/game_systems/region_service.rb +94 -0
  138. data/lib/game_machine/game_systems/region_settings.rb +13 -0
  139. data/lib/game_machine/game_systems/remote_echo.rb +14 -0
  140. data/lib/game_machine/game_systems/stress_test.rb +21 -0
  141. data/lib/game_machine/grid.rb +60 -0
  142. data/lib/game_machine/grid_replicator.rb +31 -0
  143. data/lib/game_machine/handlers/authentication.rb +55 -0
  144. data/lib/game_machine/handlers/game.rb +63 -0
  145. data/lib/game_machine/handlers/request.rb +80 -0
  146. data/lib/game_machine/hashring.rb +48 -0
  147. data/lib/game_machine/helpers/game_message.rb +159 -0
  148. data/lib/game_machine/helpers/state_machine.rb +29 -0
  149. data/lib/game_machine/java_lib.rb +51 -0
  150. data/lib/game_machine/logger.rb +39 -0
  151. data/lib/game_machine/message_buffer.rb +58 -0
  152. data/lib/game_machine/message_queue.rb +63 -0
  153. data/lib/game_machine/model.rb +125 -0
  154. data/lib/game_machine/models.rb +3 -0
  155. data/lib/game_machine/models/player_status_update.rb +8 -0
  156. data/lib/game_machine/models/region.rb +9 -0
  157. data/lib/game_machine/mono_server.rb +20 -0
  158. data/lib/game_machine/navigation.rb +4 -0
  159. data/lib/game_machine/navigation/detour.rb +20 -0
  160. data/lib/game_machine/navigation/detour_navmesh.rb +53 -0
  161. data/lib/game_machine/navigation/detour_path.rb +53 -0
  162. data/lib/game_machine/navigation/path.rb +31 -0
  163. data/lib/game_machine/object_db.rb +67 -0
  164. data/lib/game_machine/protobuf.rb +6 -0
  165. data/lib/game_machine/protobuf/game_messages.rb +24 -0
  166. data/lib/game_machine/protobuf/generate.rb +113 -0
  167. data/lib/game_machine/protobuf_extensions/entity_helper.rb +11 -0
  168. data/lib/game_machine/reloadable_monitor.rb +26 -0
  169. data/lib/game_machine/restart_watcher.rb +17 -0
  170. data/lib/game_machine/ruby_extensions/nilclass.rb +10 -0
  171. data/lib/game_machine/ruby_extensions/string.rb +17 -0
  172. data/lib/game_machine/scheduler.rb +23 -0
  173. data/lib/game_machine/securerandom.rb +6 -0
  174. data/lib/game_machine/settings.rb +11 -0
  175. data/lib/game_machine/system_monitor.rb +19 -0
  176. data/lib/game_machine/system_stats.rb +24 -0
  177. data/lib/game_machine/uniqueid.rb +23 -0
  178. data/lib/game_machine/vector.rb +95 -0
  179. data/lib/game_machine/version.rb +3 -0
  180. data/lib/game_machine/write_behind_cache.rb +164 -0
  181. data/mono/bin/csharp/common.xslt +109 -0
  182. data/mono/bin/csharp/csharp.xslt +628 -0
  183. data/mono/bin/csharp/descriptor.proto +533 -0
  184. data/mono/bin/csharp/protobuf-net.dll +0 -0
  185. data/mono/bin/csharp/protobuf-net.pdb +0 -0
  186. data/mono/bin/csharp/protobuf-net.xml +2879 -0
  187. data/mono/bin/csharp/protogen.exe.config +3 -0
  188. data/mono/bin/csharp/protogen.pdb +0 -0
  189. data/mono/bin/csharp/protogen_csharp.exe +0 -0
  190. data/mono/bin/csharp/vb.xslt +745 -0
  191. data/mono/bin/csharp/xml.xslt +26 -0
  192. data/mono/server/Makefile +6 -0
  193. data/mono/server/NLog.config +12 -0
  194. data/mono/server/NLog.dll +0 -0
  195. data/mono/server/actor.cs +37 -0
  196. data/mono/server/build.bat +3 -0
  197. data/mono/server/cscompmgd.dll +0 -0
  198. data/mono/server/iactor.cs +11 -0
  199. data/mono/server/message_router.cs +67 -0
  200. data/mono/server/message_util.cs +29 -0
  201. data/mono/server/messages.cs +1888 -0
  202. data/mono/server/protobuf-net.dll +0 -0
  203. data/mono/server/proxy_client.cs +73 -0
  204. data/mono/server/proxy_server.cs +30 -0
  205. data/mono/server/test_actor.cs +33 -0
  206. data/pathfinding/bin/premake4 +0 -0
  207. data/pathfinding/include/mesh_loader.h +28 -0
  208. data/pathfinding/include/pathfind.h +167 -0
  209. data/pathfinding/main.cpp +39 -0
  210. data/pathfinding/mesh_loader.cpp +108 -0
  211. data/pathfinding/pathfind.cpp +174 -0
  212. data/pathfinding/pathfinder.cs +66 -0
  213. data/pathfinding/premake4.lua +109 -0
  214. data/script/server.sh +109 -0
  215. data/script/watch.sh +11 -0
  216. data/spec/actor/actor_spec.rb +73 -0
  217. data/spec/actor/builder_spec.rb +56 -0
  218. data/spec/actor/ref_spec.rb +83 -0
  219. data/spec/application_spec.rb +7 -0
  220. data/spec/client_manager_spec.rb +171 -0
  221. data/spec/commands/chat_commands_spec.rb +38 -0
  222. data/spec/commands/datastore_commands_spec.rb +91 -0
  223. data/spec/commands/grid_commands_spec.rb +37 -0
  224. data/spec/commands/navigation_commands_spec.rb +51 -0
  225. data/spec/commands/player_commands_spec.rb +48 -0
  226. data/spec/commands_spec.rb +38 -0
  227. data/spec/data_stores/mapdb_spec.rb +46 -0
  228. data/spec/data_stores/redis_spec.rb +44 -0
  229. data/spec/game_systems/agents/controller_spec.rb +84 -0
  230. data/spec/game_systems/agents/test_agent.rb +10 -0
  231. data/spec/game_systems/agents/test_agent_config.rb +29 -0
  232. data/spec/game_systems/chat_manager_spec.rb +66 -0
  233. data/spec/game_systems/chat_spec.rb +187 -0
  234. data/spec/game_systems/entity_tracking_spec.rb +64 -0
  235. data/spec/game_systems/region_manager_spec.rb +138 -0
  236. data/spec/grid_spec.rb +37 -0
  237. data/spec/handlers/authentication_spec.rb +36 -0
  238. data/spec/handlers/game_spec.rb +49 -0
  239. data/spec/handlers/request_spec.rb +65 -0
  240. data/spec/hashring_spec.rb +59 -0
  241. data/spec/integration_helper.rb +120 -0
  242. data/spec/java_grid_spec.rb +89 -0
  243. data/spec/message_buffer_spec.rb +67 -0
  244. data/spec/message_expectations.rb +47 -0
  245. data/spec/message_queue_spec.rb +23 -0
  246. data/spec/misc_spec.rb +71 -0
  247. data/spec/model_spec.rb +103 -0
  248. data/spec/mono_spec.rb +36 -0
  249. data/spec/mono_test.rb +18 -0
  250. data/spec/navigation/detour_navmesh_spec.rb +34 -0
  251. data/spec/navigation/detour_path_spec.rb +25 -0
  252. data/spec/spec_helper.rb +40 -0
  253. data/spec/udp_server_spec.rb +10 -0
  254. data/spec/write_behind_cache_spec.rb +109 -0
  255. data/web/app.rb +131 -0
  256. data/web/config/trinidad.yml +4 -0
  257. data/web/controllers/auth_controller.rb +19 -0
  258. data/web/controllers/base_controller.rb +16 -0
  259. data/web/controllers/index_controller.rb +7 -0
  260. data/web/controllers/log_controller.rb +47 -0
  261. data/web/controllers/messages_controller.rb +59 -0
  262. data/web/controllers/player_register_controller.rb +15 -0
  263. data/web/log/development.log +1339 -0
  264. data/web/tmp/restart.txt +0 -0
  265. data/web/views/game_messages.haml +45 -0
  266. data/web/views/index.haml +6 -0
  267. data/web/views/layout.haml +41 -0
  268. data/web/views/logs.haml +32 -0
  269. data/web/views/player_register.haml +22 -0
  270. data/web/views/player_registered.haml +2 -0
  271. data/web/views/register_layout.haml +22 -0
  272. data/web/views/restart.haml +35 -0
  273. metadata +576 -0
@@ -0,0 +1,181 @@
1
+ module GameMachine
2
+ class Application
3
+
4
+ class << self
5
+
6
+ def initialize!(name='default', cluster=false)
7
+ AppConfig.instance.load_config(name)
8
+ config.cluster = cluster
9
+ akka.initialize!
10
+ end
11
+
12
+ def auth_handler
13
+ AuthHandlers::Base.instance
14
+ end
15
+
16
+ def data_store
17
+ DataStore.instance
18
+ end
19
+
20
+ def akka
21
+ Akka.instance
22
+ end
23
+
24
+ def config
25
+ @config ||= AppConfig.instance.config
26
+ end
27
+
28
+ def registered
29
+ @@registered ||= Set.new
30
+ end
31
+
32
+ def register(system_class)
33
+ registered << system_class
34
+ GameMachine.logger.debug "#{system_class} registered"
35
+ end
36
+
37
+ def start_actor_system
38
+ akka.start
39
+ end
40
+
41
+ def stop_actor_system
42
+ akka.stop
43
+ end
44
+
45
+ def stop
46
+ stop_actor_system
47
+ DataStore.instance.shutdown
48
+ end
49
+
50
+ def start
51
+ create_grids
52
+ game_preload
53
+ GameMachine::Actor::Reloadable.update_paths(true)
54
+ start_actor_system
55
+ data_store
56
+ start_endpoints
57
+ start_core_systems
58
+ start_handlers
59
+
60
+ if GameMachine.env == 'development'
61
+ start_development_systems
62
+ end
63
+
64
+ start_game_systems
65
+ GameLoader.new.load_all
66
+ auth_handler
67
+ start_mono
68
+
69
+ GameMachine.stdout("Game Machine start successful")
70
+
71
+ # This call blocks, make it the last thing we do
72
+ if config.http_enabled
73
+ start_http
74
+ end
75
+ end
76
+
77
+ def create_grids
78
+ Grid.load_from_config
79
+ end
80
+
81
+ def game_preload
82
+ begin
83
+ require_relative '../../games/preload.rb'
84
+ rescue LoadError => e
85
+ GameMachine.logger.info "preload.rb not found"
86
+ end
87
+ end
88
+
89
+ def start_http
90
+ require_relative '../../web/app'
91
+ end
92
+
93
+ def start_mono
94
+ if config.mono_enabled
95
+ GameMachine.logger.info "Starting mono server"
96
+ MonoServer.new.run!
97
+ end
98
+ end
99
+
100
+ def start_endpoints
101
+ if config.mono_enabled
102
+ Actor::Builder.new(Endpoints::MonoGateway).start
103
+ GameMachine.stdout(
104
+ "MonoGateway starting on #{config.mono_gateway_host}:#{config.mono_gateway_port}"
105
+ )
106
+ end
107
+ if config.tcp_enabled
108
+ Actor::Builder.new(Endpoints::Tcp).start
109
+ GameMachine.stdout(
110
+ "Tcp starting on #{config.tcp_host}:#{config.tcp_port}"
111
+ )
112
+ end
113
+
114
+ if config.udp_enabled
115
+ JavaLib::UdpServer.start(config.udp_host,config.udp_port)
116
+ Actor::Builder.new(Endpoints::UdpIncoming).with_router(
117
+ JavaLib::RoundRobinRouter,10).start
118
+
119
+ # Built in Akka udp. Performed badly we have more control by working
120
+ # directly with Netty
121
+ #Actor::Builder.new(Endpoints::Udp).start
122
+ #GameMachine.stdout(
123
+ # "UDP starting on #{config.udp_host}:#{config.udp_port}"
124
+ #)
125
+ end
126
+
127
+ end
128
+
129
+ def start_handlers
130
+ Actor::Builder.new(Handlers::Request).with_router(
131
+ JavaLib::RoundRobinRouter,config.request_handler_routers
132
+ ).start
133
+ Actor::Builder.new(Handlers::Game).with_router(
134
+ JavaLib::RoundRobinRouter,config.game_handler_routers
135
+ ).start
136
+ end
137
+
138
+ def start_development_systems
139
+ end
140
+
141
+ # TODO configurize router sizes
142
+ def start_core_systems
143
+ Actor::Builder.new(ClusterMonitor).start
144
+ Actor::Builder.new(ObjectDb).distributed(2).start
145
+ Actor::Builder.new(MessageQueue).start
146
+ Actor::Builder.new(SystemMonitor).start
147
+ Actor::Builder.new(ReloadableMonitor).start
148
+ Actor::Builder.new(Scheduler).start
149
+ Actor::Builder.new(WriteBehindCache).distributed(2).start
150
+ Actor::Builder.new(GridReplicator).start
151
+ Actor::Builder.new(ClientManager).start
152
+ Actor::Builder.new(GameSystems::EntityLoader).start
153
+ Actor::Builder.new(SystemStats).start
154
+
155
+ # Our cluster singleton for managing regions
156
+ Actor::Builder.new(GameSystems::RegionManager).singleton
157
+
158
+ # Hands out current region info to clients/other actors
159
+ Actor::Builder.new(GameSystems::RegionService).start
160
+
161
+
162
+ if ENV.has_key?('RESTARTABLE')
163
+ GameMachine.logger.info "restartable=true. Will respond to tmp/gm_restart.txt"
164
+ Actor::Builder.new(RestartWatcher).start
165
+ end
166
+ end
167
+
168
+ def start_game_systems
169
+ Actor::Builder.new(GameSystems::Devnull).start#.with_router(JavaLib::RoundRobinRouter,4).start
170
+ Actor::Builder.new(GameSystems::ObjectDbProxy).with_router(JavaLib::RoundRobinRouter,4).start
171
+ Actor::Builder.new(GameSystems::EntityTracking).with_router(JavaLib::RoundRobinRouter,10).start
172
+ Actor::Builder.new(GameSystems::LocalEcho).with_router(JavaLib::RoundRobinRouter,2).start
173
+ Actor::Builder.new(GameSystems::LocalEcho).with_name('DistributedLocalEcho').distributed(2).start
174
+ Actor::Builder.new(GameSystems::RemoteEcho).with_router(JavaLib::RoundRobinRouter,10).start
175
+ Actor::Builder.new(GameSystems::StressTest).with_router(JavaLib::RoundRobinRouter,10).start
176
+ Actor::Builder.new(GameSystems::ChatManager).start
177
+ end
178
+
179
+ end
180
+ end
181
+ end
@@ -0,0 +1,21 @@
1
+ require 'forwardable'
2
+
3
+ module GameMachine
4
+ module AuthHandlers
5
+ class Base
6
+ include Singleton
7
+ extend Forwardable
8
+
9
+ def_delegators :@handler, :authorize, :authtoken_for
10
+
11
+ def initialize
12
+ @handler = Application.config.auth_handler.constantize.new
13
+ end
14
+
15
+ def set_handler(handler_name)
16
+ @handler = handler_name.constantize.new
17
+ end
18
+ end
19
+ end
20
+ end
21
+
@@ -0,0 +1,34 @@
1
+ require 'digest/md5'
2
+ module GameMachine
3
+ module AuthHandlers
4
+ class Public
5
+
6
+ def initialize
7
+ @sessions = {}
8
+ end
9
+
10
+ def add_user(username,authtoken)
11
+ @sessions[username] = authtoken
12
+ end
13
+
14
+ def authorize(user,pass)
15
+ authtoken(user,'public')
16
+ end
17
+
18
+ def authtoken_for(user)
19
+ if @sessions.has_key?(user)
20
+ @sessions[user]
21
+ else
22
+ @sessions[user] = authtoken(user,'public')
23
+ end
24
+ end
25
+
26
+ private
27
+
28
+ def authtoken(user,pass)
29
+ Digest::MD5.hexdigest("#{user}#{pass}#{rand(10000)}")
30
+ end
31
+ end
32
+ end
33
+ end
34
+
@@ -0,0 +1,66 @@
1
+ module GameMachine
2
+ module Bot
3
+ class Chat < Actor::Base
4
+
5
+ CHAT_CHANNELS = ['region','global','help','group1']
6
+
7
+ def post_init(*args)
8
+ @client = args.first
9
+ @ctx = args[1]
10
+ @player_id = args[2]
11
+ @scheduler = get_context.system.scheduler
12
+ @dispatcher = get_context.system.dispatcher
13
+ #login
14
+ join_chat_groups
15
+ #schedule_activities
16
+ #echo
17
+ end
18
+
19
+
20
+ def schedule_activities
21
+ sleep(rand(10))
22
+ duration = JavaLib::Duration.create(rand(10) + 1, java.util.concurrent.TimeUnit::SECONDS)
23
+ @scheduler.schedule(duration, duration, get_self, "send_chat_message", @dispatcher, nil)
24
+ end
25
+
26
+ def echo
27
+ message = GameMachine::Helpers::GameMessage.new(@player_id)
28
+ message.echo_test('testing')
29
+ send_to_server(message)
30
+ end
31
+
32
+ def login
33
+ message = GameMachine::Helpers::GameMessage.new(@player_id)
34
+ end
35
+
36
+ def send_to_server(message)
37
+ @client.send_to_server(message.client_message.to_byte_array,@ctx)
38
+ end
39
+
40
+ def join_chat_groups
41
+ message = GameMachine::Helpers::GameMessage.new(@player_id)
42
+ CHAT_CHANNELS.each do |name|
43
+ message.join_chat(name)
44
+ end
45
+ send_to_server(message)
46
+ end
47
+
48
+
49
+ def send_chat_message
50
+ message = GameMachine::Helpers::GameMessage.new(@player_id)
51
+ CHAT_CHANNELS.each do |name|
52
+ message.chat_message('group','testing',name)
53
+ end
54
+ send_to_server(message)
55
+ end
56
+
57
+ def on_receive(message)
58
+ if message == 'send_chat_message'
59
+ send_chat_message
60
+ else
61
+ end
62
+ end
63
+
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,54 @@
1
+ module GameMachine
2
+ module Bot
3
+ class Client < Actor::Base
4
+
5
+ def self.start_udt_client(name,port)
6
+ UdtClient.start(name,'localhost',port)
7
+ end
8
+
9
+ def self.start(name,port)
10
+ Actor::Builder.new(self).with_name(name).start
11
+ client = start_udt_client(name,port)
12
+ master_ref = self.find(name)
13
+ master_ref.tell(client)
14
+ ctx = nil
15
+ loop do
16
+ ctx = master_ref.ask('ctx',10)
17
+ break if ctx
18
+ end
19
+ master_ref.tell('start_players')
20
+ end
21
+
22
+ def post_init(*args)
23
+ @client = nil
24
+ @ctx = nil
25
+ end
26
+
27
+ def start_player
28
+ name = "player#{@player_id}"
29
+ child = Actor::Builder.new(Bot::Chat,@client,@ctx,name,@player_id).with_parent(context).with_name(name).start
30
+ @player = child
31
+ end
32
+
33
+ def on_receive(message)
34
+ if message.is_a?(JavaLib::DefaultChannelHandlerContext)
35
+ @ctx = message
36
+ elsif message.is_a?(UdtClient)
37
+ @client = message
38
+ elsif message == 'ctx'
39
+ sender.tell(@ctx) if @ctx
40
+ elsif message == 'start_players'
41
+ GameMachine.logger.info "#{@player_id} started"
42
+ #start_player
43
+ player_id = rand(10000).to_s
44
+ m = GameMachine::Helpers::GameMessage.new(player_id)
45
+ m.player_logout
46
+ @client.send_to_server(m.to_byte_array,@ctx)
47
+ else
48
+ client_message = ClientMessage.parse_from(message.bytes)
49
+ #@player.tell(client_message,get_self)
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,204 @@
1
+
2
+ module GameMachine
3
+ class ClientManager < Actor::Base
4
+ attr_reader :local_actors, :remote_clients, :local_clients, :channel, :players, :client_to_player
5
+
6
+ def self.local_players
7
+ if @local_players
8
+ @local_players
9
+ else
10
+ @local_players = java.util.concurrent.ConcurrentHashMap.new
11
+ end
12
+ end
13
+
14
+ # Includes region + combined.
15
+ def self.local_connections
16
+ local_players.select {|player_id,type| type != 'cluster'}
17
+ end
18
+
19
+ # Cluster only connections. We should not be handling things like
20
+ # entity tracking for this type of connection. This is for stuff that is
21
+ # not latency sensitive such as chat, groups, etc..
22
+ def self.cluster_connections
23
+ local_players.select {|player_id,type| type == 'cluster'}
24
+ end
25
+
26
+ def self.send_to_player(message)
27
+ if local_players.has_key?(message.player.id)
28
+ Actor::Base.find(message.player.id).tell(message)
29
+ else
30
+ find.tell(message)
31
+ end
32
+ end
33
+
34
+ def post_init(*args)
35
+ @server = Application.config.name
36
+ @channel = 'client_events'
37
+ @local_actors = {}
38
+ @remote_clients = {}
39
+ @local_clients = {}
40
+ @players = {}
41
+ @client_to_player = {}
42
+ subscribe(channel)
43
+ ClusterMonitor.find.tell('notify_on_up')
44
+ @cluster = JavaLib::Cluster.get(getContext.system)
45
+ end
46
+
47
+ def on_receive(message)
48
+
49
+ if message.is_a?(MessageLib::Entity)
50
+
51
+ # Outgoing message to player
52
+ if message.send_to_player
53
+ send_to_remote_player(message)
54
+
55
+ # client events come from other client managers
56
+ elsif message.has_client_event
57
+ if message.client_event.sender_id.match(/#{@server}/)
58
+ return
59
+ end
60
+ process_client_event(message.client_event)
61
+
62
+ # Unregister requests come from clients only
63
+ elsif message.has_client_manager_unregister
64
+ unregister_sender(message)
65
+
66
+ # Register requests come from actors and clients
67
+ elsif message.has_client_manager_register
68
+ register_sender(message)
69
+ else
70
+ unhandled(message)
71
+ end
72
+ elsif message.is_a?(JavaLib::ClusterEvent::MemberUp)
73
+ update_new_member(address)
74
+ else
75
+ unhandled(message)
76
+ end
77
+ end
78
+
79
+ # TODO have the remote ack this, and resend it periodically until we get ack
80
+ def update_new_member(message)
81
+ client_events = MessageLib::ClientEvents.new
82
+ client_to_player.each do |client_id,player_id|
83
+ client_events.add_client_event(
84
+ create_client_event(client_id,player_id,'connected')
85
+ )
86
+ end
87
+ entity = MessageLib::Entity.new.set_id('0').set_client_events(client_events)
88
+ remote_ref = Actor::Base.find_remote(message.member.address.to_string,self.class.name)
89
+ remote_ref.tell(entity,get_self)
90
+ end
91
+
92
+ def send_to_remote_player(message)
93
+ if client_id = players.fetch(message.player.id,nil)
94
+ if remote_ref = remote_clients.fetch(client_id,nil)
95
+ remote_ref.tell(message)
96
+ end
97
+ end
98
+ end
99
+
100
+ def sender_id_to_actor_ref(sender_id)
101
+ server,name = sender_id.split('|')
102
+ Actor::Base.find_remote(server,name)
103
+ end
104
+
105
+ def process_client_event(client_event)
106
+ if client_event.event == 'disconnected'
107
+ remote_clients.delete(client_event.client_id)
108
+ client_to_player.delete(client_event.client_id)
109
+ players.delete(client_event.player_id)
110
+ GameMachine.logger.info("#{self.class.name} client #{client_event.client_id} disconnected")
111
+ elsif client_event.event == 'connected'
112
+ remote_ref = sender_id_to_actor_ref(client_event.sender_id)
113
+ remote_clients[client_event.client_id] = remote_ref
114
+ players[client_event.player_id] = client_event.client_id
115
+ client_to_player[client_event.client_id] = client_event.player_id
116
+ GameMachine.logger.info("#{self.class.name} #{Application.config.name} client #{client_event.client_id} connected")
117
+ end
118
+ end
119
+
120
+ def cluster_connection?(client_connection)
121
+ case client_connection.type
122
+ when 'cluster'
123
+ true
124
+ when 'combined'
125
+ true
126
+ else
127
+ false
128
+ end
129
+ end
130
+
131
+ def unregister_sender(message)
132
+ unregister_msg = message.client_manager_unregister
133
+ register_type = unregister_msg.register_type
134
+ name = unregister_msg.name
135
+ if register_type == 'client'
136
+ if cluster_connection?(message.client_connection)
137
+ send_client_event(name,message.player.id,'disconnected')
138
+ end
139
+
140
+ # Notify registered actors using a client manager event
141
+ send_client_manager_event(name,message.player.id,'disconnected')
142
+
143
+ local_clients.delete(name)
144
+ players.delete(message.player.id)
145
+ self.class.local_players.delete(message.player.id)
146
+ GameMachine.logger.info("#{self.class.name} client #{name} unregistered")
147
+ end
148
+ end
149
+
150
+ def register_sender(message)
151
+ register_msg = message.client_manager_register
152
+ register_type = register_msg.register_type
153
+ name = register_msg.name
154
+ events = register_msg.events
155
+
156
+ # Client register
157
+ if register_type == 'client'
158
+ if cluster_connection?(message.client_connection)
159
+ send_client_event(name,message.player.id,'connected')
160
+ end
161
+ local_clients[name] = message.client_connection
162
+ players[message.player.id] = name
163
+ self.class.local_players[message.player.id] = message.client_connection.type
164
+ get_sender.tell(message,get_self)
165
+ GameMachine.logger.info("#{self.class.name} client #{name} registered")
166
+ # Actor register
167
+ elsif register_type == 'actor'
168
+ local_actors[name] = events
169
+ end
170
+ end
171
+
172
+
173
+ def send_client_manager_event(client_id,player_id,event)
174
+ local_actors.each do |name,events|
175
+ client_manager_event = create_client_manager_event(client_id,player_id,event)
176
+ Actor::Base.find(name).tell(client_manager_event)
177
+ end
178
+ end
179
+
180
+ def create_client_manager_event(client_id,player_id,event)
181
+ client_manager_event = MessageLib::ClientManagerEvent.new.
182
+ set_client_id(client_id).set_player_id(player_id).set_event(event)
183
+ end
184
+
185
+ def create_client_event(client_id,player_id,event)
186
+ client_event = MessageLib::ClientEvent.new.set_client_id(client_id).
187
+ set_event(event).set_player_id(player_id)
188
+ client_event.set_sender_id(Application.config.name + '|' + self.class.name)
189
+ end
190
+
191
+ def send_client_event(client_id,player_id,event)
192
+ client_event = create_client_event(client_id,player_id,event)
193
+ entity = MessageLib::Entity.new.set_id('0').set_client_event(client_event)
194
+ publish = MessageLib::Publish.new
195
+ publish.set_topic(channel).set_message(entity)
196
+ MessageQueue.find.tell(publish,get_self)
197
+ end
198
+
199
+ def subscribe(topic)
200
+ message = MessageLib::Subscribe.new.set_topic(topic)
201
+ MessageQueue.find.tell(message,get_self)
202
+ end
203
+ end
204
+ end