game_machine 0.0.8

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.
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