1 /**
2 Copyright: Copyright (c) 2015-2016 Andrey Penechko.
3 License: $(WEB boost.org/LICENSE_1_0.txt, Boost License 1.0).
4 Authors: Andrey Penechko.
5 */
6 
7 module voxelman.server.plugin;
8 
9 import std.experimental.logger;
10 
11 import tharsis.prof : Profiler, DespikerSender, Zone;
12 
13 import netlib;
14 import pluginlib;
15 import pluginlib.pluginmanager;
16 
17 import voxelman.core.config;
18 import voxelman.core.events;
19 import voxelman.net.events;
20 
21 import voxelman.eventdispatcher.plugin : EventDispatcherPlugin;
22 import voxelman.command.plugin;
23 
24 
25 shared static this()
26 {
27 	auto s = new ServerPlugin;
28 	pluginRegistry.regServerPlugin(s);
29 	pluginRegistry.regServerMain(&s.run);
30 }
31 
32 class ServerPlugin : IPlugin
33 {
34 private:
35 	PluginManager pluginman;
36 	EventDispatcherPlugin evDispatcher;
37 
38 public:
39 	bool isRunning = false;
40 
41 	mixin IdAndSemverFrom!(voxelman.server.plugininfo);
42 
43 	override void init(IPluginManager pluginman)
44 	{
45 		evDispatcher = pluginman.getPlugin!EventDispatcherPlugin;
46 
47 		auto commandPlugin = pluginman.getPlugin!CommandPluginServer;
48 		commandPlugin.registerCommand("sv_stop|stop", &onStopCommand);
49 	}
50 
51 	void onStopCommand(CommandParams) { isRunning = false; }
52 
53 	void load(string[] args)
54 	{
55 		pluginman = new PluginManager;
56 		// register all plugins and managers
57 		import voxelman.pluginlib.plugininforeader : filterEnabledPlugins;
58 		foreach(p; pluginRegistry.serverPlugins.byValue.filterEnabledPlugins(args))
59 		{
60 			pluginman.registerPlugin(p);
61 		}
62 		// Actual loading sequence
63 		pluginman.initPlugins();
64 	}
65 
66 	void run(string[] args)
67 	{
68 		import std.datetime : TickDuration, Duration, Clock, usecs;
69 		import core.thread : Thread;
70 		import core.memory;
71 
72 		load(args);
73 		evDispatcher.postEvent(GameStartEvent());
74 
75 		TickDuration lastTime = Clock.currAppTick;
76 		TickDuration newTime;
77 		Duration frameTime = SERVER_FRAME_TIME_USECS.usecs;
78 
79 		// Main loop
80 		isRunning = true;
81 		while (isRunning)
82 		{
83 			newTime = Clock.currAppTick;
84 			double delta = (newTime - lastTime).usecs / 1_000_000.0;
85 			lastTime = newTime;
86 
87 			evDispatcher.postEvent(PreUpdateEvent(delta));
88 			evDispatcher.postEvent(UpdateEvent(delta));
89 			evDispatcher.postEvent(PostUpdateEvent(delta));
90 
91 			GC.collect();
92 
93 			// update time
94 			auto updateTime = Clock.currAppTick - newTime;
95 			auto sleepTime = frameTime - updateTime;
96 			if (sleepTime > Duration.zero)
97 				Thread.sleep(sleepTime);
98 		}
99 		evDispatcher.postEvent(GameStopEvent());
100 	}
101 }