messagepack instead of json

This commit is contained in:
Ben Harris 2017-03-26 21:23:49 -04:00
parent c8a7db6a29
commit 81fa60b9de
10 changed files with 237 additions and 95 deletions

1
.gitignore vendored
View File

@ -7,3 +7,4 @@ vendor/
# unneccessary
bot.err
bot.out
php_errors.log

107
bot.php
View File

@ -15,17 +15,17 @@ $dotenv = new Dotenv\Dotenv(__DIR__);
$dotenv->load();
include __DIR__.'/kaomoji.php';
include __DIR__.'/definitions.php';
include __DIR__.'/serializedarray.php';
include __DIR__.'/util_fns.php';
$yomamajokes = file("yomamajokes.txt");
$jokes = explode("---", file_get_contents(__DIR__.'/miscjokes.txt'));
$starttime = Carbon::now();
$defs = new Definitions(__DIR__.'/bot_data/definitions.json');
$imgs = new Definitions(__DIR__.'/bot_data/img_urls.json');
$cities = new Definitions(__DIR__.'/bot_data/cities.json');
$swearjar = new Definitions(__DIR__.'/bot_data/swearjar.json');
$defs = new SerializedArray(__DIR__.'/bot_data/defs.mp');
$imgs = new SerializedArray(__DIR__.'/bot_data/img_urls.mp');
$cities = new SerializedArray(__DIR__.'/bot_data/cities.mp');
$swearjar = new SerializedArray(__DIR__.'/bot_data/swearjar.mp');
$help = [];
@ -55,54 +55,57 @@ $discord->on('ready', function ($discord) use ($game, $defs, $imgs, $starttime,
$gen = charIn($text);
$first_char = $gen->current();
if ($first_char == ';') {
if (!$msg->author->bot) {
if ($first_char == ';') {
for ($qu = "", $gen->next(); $gen->current() != " " && $gen->valid(); $gen->next())
$qu .= $gen->current();
$qu = strtolower($qu);
if ($defs->get($qu, true))
send($msg, "**$qu**: " . $defs->get($qu));
if ($imgs->get($qu, true)) {
$imgfile = $imgs->get($qu);
sendFile($msg, __DIR__."/uploaded_images/$imgfile", $imgfile, $qu);
}
for ($qu = "", $gen->next(); $gen->current() != " " && $gen->valid(); $gen->next())
$qu .= $gen->current();
$qu = strtolower($qu);
if ($defs->get($qu, true))
send($msg, "**$qu**: " . $defs->get($qu));
if ($imgs->get($qu, true)) {
$imgfile = $imgs->get($qu);
sendFile($msg, __DIR__."/uploaded_images/$imgfile", $imgfile, $qu);
}
} else {
if (isDM($msg)){
$msg->channel->broadcastTyping();
askCleverbot(implode(" ", $args))->then(function ($result) use ($msg) {
send($msg, $result->output);
});
}
if (isDM($msg)) {
if (!$msg->author->bot){
$msg->channel->broadcastTyping();
askCleverbot(implode(" ", $args))->then(function ($result) use ($msg) {
send($msg, $result->output);
if ($msg->channel->guild->id === "233603102047993856") {
// arf specific
if (strpos(strtolower($text), 'dib') !== false) {
$msg->react(":dib:284335774823088129")->otherwise(function ($e) {
echo $e->getMessage(), PHP_EOL;
});
}
} else {
if (checkForSwears(strtolower($text))) {
$id = isDM($msg) ? $msg->author->id : $msg->author->user->id;
$swearcount = $swearjar->get($id, true) ? $swearjar->get($id)["swear_count"] + 1 : 1;
$swearjar->set($msg->author->id, [
'swear_count' => $swearcount,
'latest_swear' => $msg->content,
'timestamp' => Carbon::now(),
]);
$msg->react("")->otherwise(function ($e) {
echo $e->getMessage(), PHP_EOL;
});
}
}
}
if ($msg->channel->guild->id === "233603102047993856") {
if (strpos(strtolower($text), 'dib') !== false) {
$msg->react(":dib:284335774823088129")->otherwise(function ($e) {
echo $e->getMessage(), PHP_EOL;
});
}
} elseif (!$msg->author->bot) {
if (checkForSwears(strtolower($text))) {
$id = isDM($msg) ? $msg->author->id : $msg->author->user->id;
$swearcount = $swearjar->get($id, true) ? $swearjar->get($id)["swear_count"] + 1 : 1;
$swearjar->set($msg->author->id, [
'swear_count' => $swearcount,
'latest_swear' => $msg->content,
'timestamp' => Carbon::now(),
]);
$msg->react("")->otherwise(function ($e) {
echo $e->getMessage(), PHP_EOL;
});
}
}
});
@ -119,7 +122,15 @@ $discord->on('ready', function ($discord) use ($game, $defs, $imgs, $starttime,
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
$discord->registerCommand('deltest', function ($msg, $args) use ($discord) {
send($msg, "test")->then(function($result) use ($discord, $msg) {
print_r($result);
$msgs = $discord->getRepository('MessageRepository', $msg->id, '');
print_r($msgs);
// $msgs->delete($msg);
});
});
///////////////////////////////////////////////////////////
@ -848,7 +859,9 @@ $discord->registerCommand('bamboozle', function ($msg, $args) {
$discord->registerCommand('swearjar', function($msg, $args) use ($swearjar) {
$ret = "";
foreach ($swearjar->iter() as $user => $swear_info) {
$ret .= "<@$user> said '{$swear_info["latest_swear"]}' " . $swear_info["timestamp"]->diffForHumans() . "\n";
print_r($swear_info);
$date = new Carbon($swear_info["timestamp"]["date"], $swear_info["timestamp"]["timezone"]);
$ret .= "<@$user> said \"{$swear_info["latest_swear"]}\" " . $date->diffForHumans() . "\n";
}
send($msg, $ret);
}, [

View File

@ -12,6 +12,7 @@
"require": {
"team-reflex/discord-php": "dev-develop",
"guzzlehttp/guzzle": "~6.0",
"vlucas/phpdotenv": "^2.4"
"vlucas/phpdotenv": "^2.4",
"rybakit/msgpack": "^0.2.2"
}
}

46
composer.lock generated
View File

@ -4,8 +4,8 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"hash": "d3ffa44d72e9b5b5872de481afd58a05",
"content-hash": "1595e3389e81c634e7f2bf451e470b92",
"hash": "cb2746b3285ed8e6ef0c08ae94f470b1",
"content-hash": "f6ce56280951cb9d10beb2e062f6de08",
"packages": [
{
"name": "TrafficCophp/ByteBuffer",
@ -1566,6 +1566,48 @@
],
"time": "2017-01-25 14:44:14"
},
{
"name": "rybakit/msgpack",
"version": "v0.2.2",
"source": {
"type": "git",
"url": "https://github.com/rybakit/msgpack.php.git",
"reference": "62ef0f629dbbe855ffed38d1b4c4d1130b6195a9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/rybakit/msgpack.php/zipball/62ef0f629dbbe855ffed38d1b4c4d1130b6195a9",
"reference": "62ef0f629dbbe855ffed38d1b4c4d1130b6195a9",
"shasum": ""
},
"require": {
"php": "^5.4|^7.0"
},
"type": "library",
"autoload": {
"psr-4": {
"MessagePack\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Eugene Leonovich",
"email": "gen.work@gmail.com"
}
],
"description": "A pure PHP implementation of the MessagePack serialization format.",
"keywords": [
"messagepack",
"msgpack",
"pure",
"streaming"
],
"time": "2017-03-11 15:48:37"
},
{
"name": "symfony/options-resolver",
"version": "v3.2.6",

View File

@ -1,6 +1,6 @@
\relax
\@writefile{toc}{\contentsline {section}{\numberline {1}Objective}{1}}
\@writefile{toc}{\contentsline {section}{\numberline {2}Technologies}{1}}
\@writefile{toc}{\contentsline {section}{\numberline {3}What I hope to learn}{1}}
\@writefile{toc}{\contentsline {section}{\numberline {2}What I want to learn}{1}}
\@writefile{toc}{\contentsline {section}{\numberline {3}Technologies}{1}}
\@writefile{toc}{\contentsline {section}{\numberline {4}Proposed Features and Points}{2}}
\@writefile{toc}{\contentsline {section}{\numberline {5}Grading Scale}{2}}
\@writefile{toc}{\contentsline {section}{\numberline {5}Grading Scale}{3}}

View File

@ -1,4 +1,4 @@
This is pdfTeX, Version 3.14159265-2.6-1.40.17 (MiKTeX 2.9 64-bit) (preloaded format=pdflatex 2017.2.9) 25 MAR 2017 20:39
This is pdfTeX, Version 3.14159265-2.6-1.40.17 (MiKTeX 2.9 64-bit) (preloaded format=pdflatex 2017.2.9) 26 MAR 2017 21:23
entering extended mode
**./project_proposal.tex
(project_proposal.tex
@ -46,39 +46,27 @@ LaTeX Font Info: External font `cmex10' loaded for size
(Font) <8> on input line 13.
LaTeX Font Info: External font `cmex10' loaded for size
(Font) <6> on input line 13.
LaTeX Font Info: Try loading font information for OMS+cmr on input line 22.
LaTeX Font Info: Try loading font information for OMS+cmr on input line 36.
("C:\Program Files\MiKTeX 2.9\tex\latex\base\omscmr.fd"
File: omscmr.fd 2014/09/29 v2.5h Standard LaTeX font definitions
)
LaTeX Font Info: Font shape `OMS/cmr/m/n' in size <10.95> not available
(Font) Font shape `OMS/cmsy/m/n' tried instead on input line 22.
! LaTeX Error: Something's wrong--perhaps a missing \item.
See the LaTeX manual or LaTeX Companion for explanation.
Type H <return> for immediate help.
...
l.55 \end{itemize}
Try typing <return> to proceed.
If that doesn't work, type X <return> to quit.
(Font) Font shape `OMS/cmsy/m/n' tried instead on input line 36.
[1
{C:/ProgramData/MiKTeX/2.9/pdftex/config/pdftex.map}]
LaTeX Font Info: External font `cmex10' loaded for size
(Font) <10.95> on input line 64.
[2]
(Font) <10.95> on input line 92.
[2] [3]
(project_proposal.aux) )
Here is how much of TeX's memory you used:
272 strings out of 493335
3204 string characters out of 3139267
57211 words of memory out of 3000000
58211 words of memory out of 3000000
3868 multiletter control sequences out of 15000+200000
8504 words of font info for 30 fonts, out of 3000000 for 9000
1141 hyphenation exceptions out of 8191
21i,6n,19p,438b,187s stack positions out of 5000i,500n,10000p,200000b,50000s
21i,6n,19p,516b,187s stack positions out of 5000i,500n,10000p,200000b,50000s
<C:/Program Files/MiKTeX 2.9/fonts/type1/public/amsfont
s/cm/cmbx10.pfb><C:/Program Files/MiKTeX 2.9/fonts/type1/public/amsfonts/cm/cmb
x12.pfb><C:/Program Files/MiKTeX 2.9/fonts/type1/public/amsfonts/cm/cmmi10.pfb>
@ -86,9 +74,9 @@ x12.pfb><C:/Program Files/MiKTeX 2.9/fonts/type1/public/amsfonts/cm/cmmi10.pfb>
am Files/MiKTeX 2.9/fonts/type1/public/amsfonts/cm/cmr12.pfb><C:/Program Files/
MiKTeX 2.9/fonts/type1/public/amsfonts/cm/cmr17.pfb><C:/Program Files/MiKTeX 2.
9/fonts/type1/public/amsfonts/cm/cmsy10.pfb>
Output written on project_proposal.pdf (2 pages, 81076 bytes).
Output written on project_proposal.pdf (3 pages, 86679 bytes).
PDF statistics:
37 PDF objects out of 1000 (max. 8388607)
40 PDF objects out of 1000 (max. 8388607)
0 named destinations out of 1000 (max. 500000)
1 words of extra memory for PDF output out of 10000 (max. 10000000)

View File

@ -2,7 +2,7 @@
\usepackage{fullpage}
\title{Senior Project Proposal}
\title{Senior Project Proposal: Discord Chat Bot}
\date{March 22, 2017}
\author{Ben Harris}
@ -14,11 +14,25 @@
\section{Objective}
On a whim, I decided to try my hand at making a bot for the voice and text chat service Discord. I quickly became very absorbed with it and
On a whim, I decided to try my hand at making a bot for the voice and text chat service Discord. I became absorbed with it and started spending a lot of my free time on it. My goal is to create a dynamic, interactive chat experience through my bot. I would like it to be able to find images from search engines, look up weather, local time in any time zone, save arbitrary text and images, transform text to ASCII art or block emojis, play games, create and vote on polls, and more.
\section{What I want to learn}
I hope to become more familiar with PHP (especially PHP 7, which is new to me, having used 5.4 extensively). I would also like to improve the style of my code to meet the PHP Style Recommendations (PSRs). Namespacing and dependency management is also an important part of modern PHP development, so I would like to learn how to leverage Composer to manage dependencies, namespaces, and class autoloading.
It's very important that a piece of software like a chat bot not be blocked by longer-running tasks. To solve this problem, I will use the Promises paradigm to write asynchronous code.
I will need to set up and maintain a server for my bot, so I hope to learn how to create a stable, reliable, self-healing management system for the main bot process. I want to learn more about security in terms of both keeping my API tokens secure and sending HTTP requests and data over WebSockets with SSL.
I'd like to improve my skills at source control (Git). I'm comfortable with most aspects of working with Git apart from a usable branching model and dealing with merge conflicts.
\section{Technologies}
\begin{itemize}
\item Discord Bot API (RESTful)
\item DiscordPHP (client for interacting with the API)
\item Ubuntu Server
@ -37,39 +51,53 @@
\section{What I hope to learn}
I hope to become more familiar with PHP (especially PHP 7, which is new to me, having used 5.4 extensively). I would also like to improve the style of my code to meet the PHP Style Recommendations (PSRs). Namespacing and dependency management is also an important part of modern PHP development, so I would like to learn how to leverage Composer to manage dependencies, namespaces, and class autoloading.
I will need to set up and maintain a server for my bot, so I hope to learn how to create a stable, reliable, self-healing management system for the main bot process.
\section{Proposed Features and Points}
\begin{itemize}
\begin{itemize}
\item Get User Info [1 pts]
\item Get Profile Photo for arbitrary User [1 pts]
\item Get Server Info [2 pts]
\item Display Bot Status/Uptime [1 pts]
\item Send direct message to any user [1 pts]
\item Permissions for commands based on user's permissions [2 pts]
\item Talk to Cleverbot [3 pts]
\item Save images and retrieve them later [5 pts]
\item Save text and retrieve it later [2 pts]
\item Send me a text message [2 pts]
\item Send emails to a saved address for a user [2 pts]
\item Internet lookups
\begin{itemize}
\item Weather for any city [3 pts]
\item Time for any city (by looking up timezone) and formatting correctly [3 pts]
\item Save a preferred city for each user for time and weather [2 pts]
\item Look up a random joke [2 pts]
\item Send an image from Google Image Search Results [5 pts]
\item Stream music from YouTube to a voice channel [10 pts]
\end{itemize}
\item Create and vote on polls [5 pts]
\item Chat games (TicTacToe, Hangman, or both) [10 pts]
\item Text transform (block emojis, unicode fonts, and ASCII art) [3 pts]
\item Roll an n-sided die [1 pts]
\item 8-Ball style fortunes [2 pts]
\end{itemize}
\end{itemize}
\section{Grading Scale}
50 points total.
70 points total.
45+ =$>$ A
63+ =$>$ A
40+ =$>$ B
56+ =$>$ B
35+ =$>$ C
49+ =$>$ C
30+ =$>$ D
42+ =$>$ D
25+ =$>$ F
35+ =$>$ F
The items that have a higher point value are the features that I am least familiar with and will require the most effort/learning on my part.

69
serializedarray.php Normal file
View File

@ -0,0 +1,69 @@
<?php
include __DIR__.'/vendor/autoload.php';
class SerializedArray {
protected $data;
protected $filepath;
public function __construct($filepath)
{
$this->filepath = $filepath;
if (!is_file($this->filepath)) throw new Exception("Invalid filepath");
$rawfiledata = file_get_contents($this->filepath);
if (strlen($rawfiledata) > 3) {
$this->data = (new MessagePack\Unpacker())->unpack($rawfiledata);
}
}
public function __toString()
{
return print_r($this->data, true);
}
public function get($key, $nullable = false)
{
return $this->data[$key] ?? ($nullable ? false : "**not set**");
}
public function set($key, $val)
{
$this->data[$key] = $val;
$this->save();
}
public function unset($key)
{
unset($this->data[$key]);
$this->save();
}
public function getKeys()
{
return array_keys($this->data);
}
private function save()
{
file_put_contents($this->filepath, (new MessagePack\Packer())->packMap($this->data));
}
public function print()
{
$ret = [];
foreach ($this->data as $key => $val) {
$ret[] = $key . ": " . $val;
}
return implode(", ", $ret);
}
public function iter()
{
foreach ($this->data as $key => $val) {
yield $key => $val;
}
}
}