1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
|
package MasterServer::Core::Core;
use strict;
use warnings;
use AnyEvent;
use Exporter 'import';
use DBI;
our @EXPORT = qw | halt select_database_type main |;
################################################################################
## Handle shutting down the program in case a fatal error occurs.
################################################################################
sub halt {
my $self = shift;
# log shutdown
$self->log("stop", "Stopping the masterserver.");
# clear all other timers, network servers, etc
$self->{dbh}->disconnect() if (defined $self->{dbh});
$self->{dbh} = undef;
$self->{scope} = undef;
# and send signal to condition var to let the loops end
$self->{must_halt}->send;
# log halt
$self->log("stop", "Shutting down NOW!");
# time for a beer.
exit;
}
################################################################################
## Set up the database connection
## determine the type of database and load the appropriate module
################################################################################
sub select_database_type {
my $self = shift;
# read from login
my @db_type = split(':', $self->{dblogin}->[0]);
# format supported?
if ( "Pg SQLite mysql" =~ m/$db_type[1]/i) {
# inform us what DB we try to load
$self->log("load","Loading $db_type[1] database module.");
# load dbd and tables/queries for this db type
MasterServer::load_recursive("MasterServer::Database::$db_type[1]");
# Connect to database
$self->{dbh} = $self->database_login();
# and test whether we succeeded.
$self->halt() unless (defined $self->{dbh});
}
else {
# raise error and halt
$self->log("fatal", "The masterserver could not determine the chosen database type.");
$self->halt();
}
}
################################################################################
## Initialize all processes and start various functions
################################################################################
sub main {
my $self = shift;
# condition var prevents or allows the program from ending
$self->{must_halt} = AnyEvent->condvar;
# force version info
$self->version();
# print startup
print "Running...\n";
# keep several objects alive outside their original scope
$self->{scope} = ();
# startup procedure information
$self->log("info", "");
$self->log("info", "");
$self->log("info", "333networks Master Server Application.");
$self->log("info", "Hostname: $self->{masterserver_hostname}");
$self->log("info", "Build: $self->{build_type}");
$self->log("info", "Version: $self->{build_version}");
$self->log("info", "Author: $self->{build_author}");
$self->log("info", "Logs: $self->{log_dir}");
# determine the type of database and load the appropriate module
$self->select_database_type();
#
# Prepare necessary tasks for running the masterserver
#
# (re)load the list with ciphers from the config file, into the database
$self->load_ciphers();
# set first run flag to avoid ignoring servers after downtime
$self->{firstrun} = undef;
$self->{firstruntime} = time;
###
#
# activate all schedulers and functions
#
###
#
# Timers
#
# tasks that are executed once or twice per hour
$self->{scope}->{long_periodic_tasks} = $self->long_periodic_tasks();
#
# tasks that are executed every few minutes
$self->{scope}->{short_periodic_tasks} = $self->short_periodic_tasks();
#
# tasks that are executed every few milliseconds
$self->{scope}->{udp_ticker} = $self->udp_ticker();
#
# Network listeners
#
# start the listening service (listen for UDP beacons)
$self->{scope}->{beacon_catcher} = $self->beacon_catcher();
#
# provide server lists to clients with the browser host server
$self->{scope}->{browser_host} = $self->browser_host();
# all modules loaded. Running...
$self->log("info", "All modules loaded. Masterserver is now running.");
# prevent main program from ending prematurely
$self->{must_halt}->recv;
}
1;
|