Skip to content

Commit

Permalink
Fixed many bugs, got MySQL database working
Browse files Browse the repository at this point in the history
  • Loading branch information
PEMapModder committed Jan 22, 2016
1 parent 4695a6b commit 271187d
Show file tree
Hide file tree
Showing 20 changed files with 298 additions and 51 deletions.
38 changes: 30 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,21 @@ HereAuth
===
> Your auth plugin is here, for you. The PocketMine auth plugin with the most customization ever.
Phar download:
### Phar download
* [Latest development build](compile/HereAuth_Dev.phar)
* [Latest beta build](compile/HereAuth_Beta.phar)
* [Latest release](compile/HereAuth_RC.phar)

#### Latest Dev build number
`135`

#### Latest Beta build number
`136`

#### Latest RC build number
`nil`

### License
```
Copyright (C) 2016 PEMapModder
This program is free software: you can redistribute it and/or modify
Expand All @@ -15,10 +25,11 @@ the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
```

Project created (first byte written): Jan 14 2016
### Project history:
First byte written: Jan 14 2016
First beta released: Jan 21 2016

Features
===
### Features
- [x] Authentication by typing password into chat
- [x] sorry, no alternative, but there is an option to disallow passwords starting with slashes
- [x] Blocks player from talking password into chat directly
Expand All @@ -28,8 +39,8 @@ Features
- [x] Advanced session control system over PocketMine's default one
- [x] PocketMine by default kicks the old player if a player joins with the same name as an online player.
- [x] HereAuth checks if the players have the same client secret (and IP address too, optional in config). If they do, that means it is from the same genuine player, so kick the old player. If they aren't, this most likely means that the new player is trying to get the old player kicked.
- [ ] Multiple database types supported
- [ ] MySQL
- [x] Multiple database types supported
- [x] MySQL
- [x] filesystem (zlib-encoded JSON + SQLite3)
- [x] External database through other plugins
- [x] Count-limit or rate-limit accounts per IP (account-throttle)
Expand All @@ -41,6 +52,12 @@ Features
- [ ] Don't let impostors see what is in your inventory!
- [ ] Don't let impostors see where you are!
- [ ] Don't let impostors see what messages other plugins want to send to you!
- [ ] Account management commands
- [ ] `/chpw`: change password
- [ ] `/unreg`: unregister account
- [ ] `/opt`: change account options (things in `config.yml`:`DefaultSettings`)
- [x] `/lock`: temporarily logout (deauthenticate) without entirely leaving the server
- [ ] `/rename`: rename account
- [x] Server-customized events to block when not authenticated
- [x] Only blocks events that you want to block!
- [x] Enforced password control
Expand All @@ -50,6 +67,11 @@ Features
- [x] Extensive audit logging
- [ ] An extensive API (W.I.P.)

Entry script
===
## Entry script
Open this phar directly with PHP binaries to automatically extract the config files.

## Code Statistics
* 50 PHP source files
* 3687 lines of PHP code
* minus 750 lines of license header
* Total: 2937
6 changes: 4 additions & 2 deletions compile.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,14 +81,16 @@ function parsePerms(SimpleXMLElement $element, array $parents){
$NAME = $info->name;

$CLASS = "Dev";
$BUILD_NUMBER = $info->nextBuild++;

$opts = getopt("", ["rc", "beta"]);
if(isset($opts["beta"])){
$CLASS = "Beta";
}elseif(isset($opts["rc"])){
$CLASS = "RC";
}

$VERSION = $info->version->major . "." . $info->version->minor . "-" . $CLASS . "#" . ($buildNumber = $info->nextBuild++);
$VERSION = $info->version->major . "." . $info->version->minor . "-" . $CLASS . "#" . $BUILD_NUMBER;
file_put_contents("compile/info.json", json_encode($info, JSON_BIGINT_AS_STRING | JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));

$permissions = [];
Expand Down Expand Up @@ -127,7 +129,7 @@ function parsePerms(SimpleXMLElement $element, array $parents){
addDir($phar, "entry", "entry");
addDir($phar, "resources", "resources");
$phar->stopBuffering();
echo "Created $NAME $CLASS #$buildNumber", PHP_EOL;
echo "Created $NAME $CLASS #$BUILD_NUMBER", PHP_EOL;

exec("git add " . escapeshellarg($file));
if(is_file("priv/postCompile.php")){
Expand Down
Binary file modified compile/HereAuth_Beta.phar
Binary file not shown.
Binary file modified compile/HereAuth_Dev.phar
Binary file not shown.
2 changes: 1 addition & 1 deletion compile/info.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@
"major": 1,
"minor": 0
},
"nextBuild": 84
"nextBuild": 137
}
2 changes: 0 additions & 2 deletions entry/entry.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@
* @author PEMapModder
*/

echo "(Ignore the line above; it is just a harmless annoying Shebang line)", "\n";

//if(version_compare(PHP_VERSION, "7.0.0", "<")){
// echo "Fatal: This entry script requires PHP >=7.0.0!\n";
// exit;
Expand Down
4 changes: 2 additions & 2 deletions resources/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ RemindLogin:
Register: Please register by typing password into chat
Login: Please login by typing password into chat
# Type of message.
# Options: chat, popup, tip
# Options: chat, popup, tip, none
Type: popup
# Frequency interval, in seconds, of how often to send the message
# Value is rounded down to 0.05 second
Expand Down Expand Up @@ -248,7 +248,7 @@ Appearance:
# but without potion effect bubbles
Invisible: false
# Add text before player nametag
PrependNametag: "§7["
PrependNametag: "§c["
# Add text after player nametag
AppendNametag: "]"

Expand Down
45 changes: 31 additions & 14 deletions src/HereAuth/Database/MySQL/MySQLDatabase.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,28 +31,32 @@ class MySQLDatabase implements Database{
public function __construct(HereAuth $main){
$this->main = $main;
$this->crd = MySQLCredentials::fromConfig($main->getConfig());
$this->mainTable = $main->getConfig()->getNested("Database.MySQL.TablePrefix", "hereauth_") . "accounts";
$this->mainTable = $main->getConfig()->getNested("Database.MySQL.TablePrefix", "hereauth_") . "accs";
$main->getLogger()->info("Initializing database...");
$db = $this->createMysqliInstance($this->crd);
$db = self::createMysqliInstance($this->crd);
$db->query("CREATE TABLE IF NOT EXISTS `$this->mainTable` (
name VARCHAR(63) PRIMARY KEY,
hash BINARY(64),
register INT,
login INT,
register INT UNSIGNED,
login INT UNSIGNED,
ip VARCHAR(50),
secret BINARY(16),
uuid BINARY(16),
skin VARBINARY(32767),
opts VARCHAR(32767),
multihash VARCHAR(32767)
skin BINARY(64),
opts VARCHAR(1024),
multihash VARCHAR(1024)
)");
if(isset($db->error) and $db->error){
throw new \RuntimeException($db->error);
}
$db->close();
}

public function loadFor($name, $identifier){
$this->main->getServer()->getScheduler()->scheduleAsyncTask(new MySQLLoadPlayerTask($this, $name, $identifier));
}

public function saveData($name, AccountInfo $info){
public function saveData(AccountInfo $info){
$this->main->getServer()->getScheduler()->scheduleAsyncTask(new MySQLSavePlayerTask($this, $info));
}

Expand All @@ -62,33 +66,39 @@ public function renameAccount($oldName, $newName, callable $hook){
}

public function unregisterAccount($name, callable $hook){
// TODO: Implement unregisterAccount() method.
$hookId = $this->main->getFridge()->store($hook);
$this->main->getServer()->getScheduler()->scheduleAsyncTask(new MySQLUnregisterPlayerTask($this, $name, $hookId));
}

public function passesLimit($ip, $limit, $time, $identifier){
}

public function close(){
// TODO: Implement close() method.
}

/**
* @param MySQLCredentials $crd
* @param HereAuth $main
*
* @return \mysqli
*
* @throws \InvalidKeyException
*/
public static function createMysqliInstance(MySQLCredentials $crd){
public static function createMysqliInstance(MySQLCredentials $crd, HereAuth $main = null){
/** @noinspection PhpUsageOfSilenceOperatorInspection */
$db = @new \mysqli($crd->host, $crd->username, $crd->password, $crd->schema, $crd->port, $crd->socket);
if($db->connect_error === "Unknown database '$crd->schema'"){
/** @noinspection PhpUsageOfSilenceOperatorInspection */
$db = @new \mysqli($crd->host, $crd->username, $crd->password, "", $crd->port, $crd->socket);
$createSchema = true;
}
if($db->connect_error){
throw new \InvalidKeyException($db->connect_error);
}
if(isset($createSchema)){
if($main !== null){
$main->getLogger()->notice("Creating nonexistent `$crd->schema`...");
}
$db->query("CREATE SCHEMA `$crd->schema`");
if($db->error){
if(isset($db->error)){
throw new \InvalidKeyException("Schema does not exist and cannot be created");
}
}
Expand All @@ -108,4 +118,11 @@ public function getCredentials(){
public function getMainTable(){
return $this->mainTable;
}

/**
* @return HereAuth
*/
public function getMain(){
return $this->main;
}
}
37 changes: 37 additions & 0 deletions src/HereAuth/Database/MySQL/MySQLEscapeInvokable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/

namespace HereAuth\Database\MySQL;

use HereAuth\Utils\Invokable;

class MySQLEscapeInvokable extends Invokable{
/** @type \mysqli */
private $db;

public function __construct(\mysqli $db){
$this->db = $db;
}

public function invoke($string){
return "'" . $this->db->escape_string($string) . "'";
}
}
1 change: 1 addition & 0 deletions src/HereAuth/Database/MySQL/MySQLLoadPlayerTask.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ public function onRun(){
$result->close();
if(!is_array($row)){
$this->setResult(false, false);
return;
}
$row["hash"] = rtrim($row["hash"]);
$row["skin"] = zlib_decode($row["skin"]);
Expand Down
66 changes: 66 additions & 0 deletions src/HereAuth/Database/MySQL/MySQLPassLimitCheckTask.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?php

/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/

namespace HereAuth\Database\MySQL;

use HereAuth\HereAuth;
use pocketmine\Server;

class MySQLPassLimitCheckTask extends AsyncQueryTask{
/** @type string */
private $tableName;
/** @type string */
private $ip;
/** @type int */
private $limit, $since;
/** @type int */
private $identifier;
/** @type bool */
private $passed;

public function __construct(MySQLDatabase $database, $ip, $limit, $time, $identifier){
parent::__construct($database->getCredentials());
$this->tableName = $database->getMainTable();
$this->ip = $ip;
$this->limit = $limit;
$this->since = time() - $time;
$this->identifier = $identifier;
}

public function onRun(){
$db = $this->getMysqli();
$result = $db->query("SELECT COUNT(*) AS cnt FROM `$this->tableName` WHERE ip='{$db->escape_string($this->ip)}' AND register >= $this->since");
$row = $result->fetch_assoc();
$result->close();
$cnt = (int) $row["cnt"];
$this->passed = $cnt < $this->limit;
}

public function onCompletion(Server $server){
if(!$this->passed){
$main = HereAuth::getInstance($server);
if($main !== null){
$player = $main->getPlayerById($this->identifier);
$player->kick("You created too many accounts!", false);
}
}
}
}
9 changes: 5 additions & 4 deletions src/HereAuth/Database/MySQL/MySQLSavePlayerTask.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,10 @@ public function __construct(MySQLDatabase $db, AccountInfo $info){

public function onRun(){
$db = $this->getMysqli();
$query = $this->info->getDatabaseQuery($this->tableName, function ($string) use ($db){
return "'" . $db->escape_string($string) . "'";
});
$db->query($query);
$query = $this->info->getDatabaseQuery($this->tableName, new MySQLEscapeInvokable($db));
$result = $db->query($query);
if($result === false){
echo "Error: $db->error\n";
}
}
}

0 comments on commit 271187d

Please sign in to comment.