Passed
Branch master (89a0e8)
by
unknown
06:01
created

Dramiel.php (5 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * The MIT License (MIT)
4
 *
5
 * Copyright (c) 2016  Robert Sardinia
6
 *
7
 * Permission is hereby granted, free of charge, to any person obtaining a copy
8
 * of this software and associated documentation files (the "Software"), to deal
9
 * in the Software without restriction, including without limitation the rights
10
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
 * copies of the Software, and to permit persons to whom the Software is
12
 * furnished to do so, subject to the following conditions:
13
 *
14
 * The above copyright notice and this permission notice shall be included in all
15
 * copies or substantial portions of the Software.
16
 *
17
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
 * SOFTWARE.
24
 */
25
26
// Require the vendor stuff
27
/** @noinspection PhpIncludeInspection */
28
require_once __DIR__ . '/vendor/autoload.php';
29
30
// Setup logger
31
use Discord\Discord;
32
use Discord\Parts\User\Game;
33
use Discord\WebSockets\Event;
34
use Discord\WebSockets\WebSocket;
35
use Monolog\Handler\StreamHandler;
36
use Monolog\Logger;
37
38
// More memory allowance
39
ini_set('memory_limit', '1024M');
40
41
// Just in case we get launched from somewhere else
42
chdir(__DIR__);
43
44
// Enable garbage collection
45
gc_enable();
46
47
// When the bot started
48
$startTime = time();
49
50
// create a log channel
51
$logger = new Logger('Dramiel');
52
$logger->pushHandler(new StreamHandler(__DIR__ . '/log/dramielLog.log', Logger::INFO));
53
$logger->addInfo('Logger Initiated');
54
55
GLOBAL $logger;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
56
57
// Require the config
58
if (file_exists('config/config.php')) {
59
    /** @noinspection PhpIncludeInspection */
60
    require_once 'config/config.php';
61
} else {
62
    $logger->error('config.php not found (you might wanna start by editing and renaming config_new.php)');
63
    die();
64
}
65
66
// Load the library files (Probably a prettier way to do this that i haven't thought up yet)
67
foreach (glob(__DIR__ . '/src/lib/*.php') as $lib) {
68
    /** @noinspection PhpIncludeInspection */
69
    require_once $lib;
70
}
71
72
//Startup DB Check
73
updateDramielDB($logger);
74
75
// Init Discord
76
$discord = new Discord(['token' => $config['bot']['token']]);
77
78
// Load tick plugins
79
$pluginDirs = array('src/plugins/onTick/*.php');
80
$logger->info('Loading background plugins');
81
$plugins = array();
82
$pluginsT = array();
83
foreach ($pluginDirs as $dir) {
84
    foreach (glob($dir) as $plugin) {
85
        // Only load the plugins we want to load, according to the config
86
        if (!in_array(str_replace('.php', '', basename($plugin)), $config['enabledPlugins'])) {
87
            continue;
88
        }
89
90
        /** @noinspection PhpIncludeInspection */
91
        require_once $plugin;
92
        $fileName = str_replace('.php', '', basename($plugin));
93
        $p = new $fileName();
94
        $p->init($config, $discord, $logger);
95
        $pluginsT[] = $p;
96
    }
97
}
98
// Number of plugins loaded
99
$logger->info('Loaded: ' . count($pluginsT) . ' background plugins');
100
101
if ($config['bot']['silentMode'] == 'false' || !isset($config['bot']['silentMode'])) {
102
// Load chat plugins
103
    $pluginDirs = array('src/plugins/onMessage/*.php', 'src/plugins/admin/*.php');
104
    $adminPlugins = array('setNickname', 'getLog', 'setGame', 'setAvatar');
105
    $logger->addInfo('Loading in chat plugins');
106
    $plugins = array();
107
    foreach ($pluginDirs as $dir) {
108
        foreach (glob($dir) as $plugin) {
109
            // Only load the plugins we want to load, according to the config
110
            if (!in_array(str_replace('.php', '', basename($plugin)), $config['enabledPlugins']) && !in_array(str_replace('.php', '', basename($plugin)), $adminPlugins)) {
111
                continue;
112
            }
113
114
            /** @noinspection PhpIncludeInspection */
115
            require_once $plugin;
116
            $fileName = str_replace('.php', '', basename($plugin));
117
            $p = new $fileName();
118
            $p->init($config, $discord, $logger);
119
            $plugins[] = $p;
120
        }
121
    }
122
123
// Number of chat plugins loaded
124
    $logger->addInfo('Loaded: ' . count($plugins) . ' chat plugins');
125
}
126
127
// Clear queue at restart if it's too high
128
clearQueueCheck();
129
130
//Check initial server state (tick plugins will not run if eve is offline)
131
$crestData = json_decode(downloadData('https://crest-tq.eveonline.com/'), true);
132
$crestStatus = isset($crestData['serviceStatus']) ? $crestData['serviceStatus'] : 'offline';
133
setPermCache('serverState', $crestStatus);
134
setPermCache('statusLastState', $crestStatus);
135
$logger->addInfo("serverState: EVE is currently {$crestStatus}");
136
137
//Clean up any outdated databases
138
dbPrune();
139
140
$discord->on(
141
    'ready',
142
    function($discord) use ($logger, $config, $plugins, $pluginsT) {
143
        // In here we can access any of the WebSocket events.
144
        //
145
        // There is a list of event constants that you can
146
        // find here: https://teamreflex.github.io/DiscordPHP/classes/Discord.WebSockets.Event.html
147
        //
148
        // We will echo to the console that the WebSocket is ready.
149
        $logger->addInfo('Discord WebSocket is ready!' . PHP_EOL);
150
151
        //Clear queue if it's super backed up
152
153
154
        //Set Initial Game
155
        $gameTitle = $config['bot']['game'];
156
        if (null !== getPermCache('botGame')) {
157
            $gameTitle = getPermCache('botGame');
158
        }
159
        $game = $discord->factory(Game::class, [
160
            'name' => $gameTitle,
161
        ]);
162
        $discord->updatePresence($game);
163
164
        // Server Status Check (tick plugins will not run if eve is offline)
165
        $discord->loop->addPeriodicTimer(60, function() use ($logger) {
166
            $crestData = json_decode(downloadData('https://crest-tq.eveonline.com/'), true);
167
            $crestStatus = isset($crestData['serviceStatus']) ? $crestData['serviceStatus'] : 'offline';
168
            setPermCache('serverState', $crestStatus);
169
        });
170
171
        // Run the Tick plugins
172
        $discord->loop->addPeriodicTimer(3, function() use ($pluginsT) {
173
            foreach ($pluginsT as $plugin) {
174
                $plugin->tick();
175
            }
176
        });
177
178
        // Message queue
179
        $discord->loop->addPeriodicTimer(7, function() use ($discord, $logger) {
180
            $x = 0;
181
            while ($x < 3) {
182
                $id = getOldestMessage();
0 ignored issues
show
Are you sure the assignment to $id is correct as getOldestMessage() seems to always returns null.
Loading history...
183
                $id = $id['MIN(id)'];
184
                if (null === $id) {
185
                    $id = 1;
186
                }
187
                $queuedMessage = getQueuedMessage($id);
0 ignored issues
show
Are you sure the assignment to $queuedMessage is correct as getQueuedMessage($id) (which targets getQueuedMessage()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
188
                if (null !== $queuedMessage) {
189
                    //Check if queued item is corrupt and delete it if it is
190
                    if (null === $queuedMessage['guild'] || null === $queuedMessage['channel'] || null === $queuedMessage['message']) {
191
                        $logger->addInfo("QueueProcessing Error- Item #{$id} : Queued item is badly formed, removing it from the queue");
192
                        clearQueuedMessages($id);
193
                        continue;
194
                    }
195
                    $guild = $discord->guilds->get('id', $queuedMessage['guild']);
196
                    //Check if guild is bad
197
                    if (null === $guild) {
198
                        $logger->addInfo("QueueProcessing Error- Item #{$id} : Guild provided is incorrect, removing it from the queue");
199
                        clearQueuedMessages($id);
200
                        continue;
201
                    }
202
                    $channel = $guild->channels->get('id', (int)$queuedMessage['channel']);
203
                    //Check if channel is bad
204
                    if (null === $channel) {
205
                        $logger->addInfo("QueueProcessing Error- Item #{$id} : Channel provided is incorrect, removing it from the queue");
206
                        clearQueuedMessages($id);
207
                        continue;
208
                    }
209
                    $logger->addInfo("QueueProcessing - Completing queued item #{$id}");
210
                    $channel->sendMessage($queuedMessage['message'], false, null);
211
                    clearQueuedMessages($id);
212
                }
213
                $x++;
214
            }
215
        });
216
217
        // Rename queue
218
        $discord->loop->addPeriodicTimer(10, function() use ($discord, $logger) {
219
            $x = 0;
220
            while ($x < 4) {
221
                $id = getOldestRename();
0 ignored issues
show
Are you sure the assignment to $id is correct as getOldestRename() seems to always returns null.
Loading history...
222
                $id = $id['MIN(id)'];
223
                if (null === $id) {
224
                    $id = 1;
225
                    $x = 4;
226
                }
227
                $queuedRename = getQueuedRename($id);
0 ignored issues
show
Are you sure the assignment to $queuedRename is correct as getQueuedRename($id) (which targets getQueuedRename()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
228
                if (null !== $queuedRename) {
229
                    //Check if queued item is corrupt and delete it if it is
230
                    if (null === $queuedRename['guild'] || null === $queuedRename['discordID']) {
231
                        clearQueuedRename($id);
232
                    }
233
                    $guild = $discord->guilds->get('id', $queuedRename['guild']);
234
                    $member = $guild->members->get('id', $queuedRename['discordID']);
235
                    $member->setNickname($queuedRename['nick']);
236
                    clearQueuedRename($id);
237
                }
238
                $x++;
239
            }
240
        });
241
242
        // Mem cleanup every 30 minutes
243
        $discord->loop->addPeriodicTimer(1800, function() use ($logger) {
244
            $logger->addInfo('Memory in use: ' . memory_get_usage() / 1024 / 1024 . 'MB');
245
            gc_collect_cycles(); // Collect garbage
246
            $logger->addInfo('Memory in use after garbage collection: ' . memory_get_usage() / 1024 / 1024 . 'MB');
247
        });
248
249
        $discord->on(
250
            Event::MESSAGE_CREATE,
251
            function($message) use ($logger, $config, $plugins) {
252
253
                $msgData = array(
254
                    'message' => array(
255
                        'timestamp' => @$message->timestamp,
256
                        'id' => @$message->id,
257
                        'message' => @$message->content,
258
                        'channelID' => @$message->channel_id,
259
                        'from' => @$message->author->username,
260
                        'fromID' => @$message->author->id,
261
                        'fromDiscriminator' => @$message->author->discriminator,
262
                        'fromAvatar' => @$message->author->avatar
263
                    )
264
                );
265
266
                if ($message->content == '(╯°□°)╯︵ ┻━┻') {
267
                    $message->reply('┬─┬ ノ( ゜-゜ノ)');
268
                }
269
270
                // Check for plugins
271
                if (isset($message->content[0])) {
272
                    if ($message->content[0] == $config['bot']['trigger']) {
273
                        foreach ($plugins as $plugin) {
274
                            try {
275
                                $plugin->onMessage($msgData, $message);
276
                            } catch (Exception $e) {
277
                                $logger->addError('Error: ' . $e->getMessage());
278
                            }
279
                        }
280
                    }
281
                }
282
            }
283
        );
284
    }
285
);
286
$discord->on(
287
    'error',
288
    function($error) use ($logger) {
289
        $logger->addError($error);
290
        exit(1);
291
    }
292
);
293
$discord->on(
294
    'reconnecting',
295
    function() use ($logger) {
296
        $logger->addInfo('Websocket is reconnecting..');
297
    });
298
$discord->on(
299
    'reconnected',
300
    function() use ($logger) {
301
        $logger->addInfo('Websocket was reconnected..');
302
    });
303
// Now we will run the ReactPHP Event Loop!
304
$discord->run();
305
306