First public release of MyAAC

This commit is contained in:
slawkens1
2017-05-01 20:02:45 +02:00
parent 31172b4883
commit b5362d0654
2016 changed files with 114481 additions and 0 deletions

View File

@@ -0,0 +1 @@
deny from all

48
system/libs/pot/AUTHORS Normal file
View File

@@ -0,0 +1,48 @@
During long time of OpenTibia development process many people worked
on it and cooperated with us. Note that OpenTibia is not only Open
Tibia Server, but also all related projects. Thanks to everyone who
helped those projects to grow. Here is a list, far from being
complete, of people that is contributing or contributed in the past to
OpenTibia.
Currently active:
Tliff - Developer, OpenTibia leader, Forum administrator
SimOne - Developer
Spin - Developer
Primer - Developer
Pedro B. - Developer
Wrzasq - Developer
GriZzm0 - Scripting
Heliton - Scripting
Winghawk - Item list, Scripts
Nostradamus - Scripting
Arkold Thos - Linux porter
Yorick - Fansite , Forum administrator
Pekay - README Documentation, Forum administrator
Nuker - Forum administrator
verkon - Forum administrator
Inactive developers:
Shi'Voc - Initial project developer
Acrimon - Initial project developer
Reebow - Developer, special protocol support
Aire - Developer
Haktivex - Developer
Fandoras - Developer
TiMMit - Developer
Decar - Fansite
Matkus - Developer
Privateer - Documentation on the protocol
Torvik - Item list
Snack - Developer
j4K3xBl4sT3r - Developer
Smygflik - Developer
Anstice - Developer
Jiddo - Scripting
the fike - Developer (advisory/optimization)
Vitor - Developer (advisory/optimization)
bruno - ODBC driver
And special thanks to all otfans.net moderators.

112
system/libs/pot/CHANGELOG Normal file
View File

@@ -0,0 +1,112 @@
[0.1.4]
* Updated for last database changes. <wrzasq>
* Updated OTAdmin implementation. <wrzasq>
* Binary information protocol support. <wrzasq>
* Server status routines grouped. <wrzasq>
* Bugfixes. <wrzasq>
[0.1.3]
* Updated documentation. <wrzasq>
* VIP list support. <wrzasq>
* Bans lists. <wrzasq>
* PHK and PHAR packages. <wrzasq>
* Separated make targets for POT package and it's documentation. <wrzasq>
* More stricted parameters and results types. <wrzasq>
* Added display driver interface for non-database resources. <wrzasq>
* Added existence checking methods. <wrzasq>
* Added __get() and __set() methods to OTS_Admin. <wrzasq>
* PDO connection is now set to throw exceptions on SQL errors instead of silence them. <wrzasq>
* Code optimalisation. <wrzasq>
* Bugfixes. <wrzasq>
[0.1.2]
* OTAdmin protocol support. <wrzasq>
* Supports bank balance. <wrzasq>
* getStorage()/setStorage() methods in OTS_Player class. <wrzasq>
* More secured. <wrzasq>
* Fixed buffered streams to use little-endian storage (like Open Tibia does). <wrzasq>
* Implemented NetworkMessage. <wrzasq>
[0.1.1]
* Loading groups by names. <wrzasq>
* Constructors with optional identifier argument for automatical object loading. <wrzasq>
* OTS_Toolbox class. <wrzasq>
* Access calculations in OTS_Account class. <wrzasq>
* E_OTS_General class. <wrzasq>
[0.1.0]
* Houses support. <wrzasq>
* No need to call POT::createObject(). <wrzasq>
* Separated data/ directory resources loaders. <wrzasq>
* Default data/ directory resources instances within POT class. <wrzasq>
* Each data/ directory resource reader class implements an Iterator/IteratorAggregate, Countable and ArrayAccess interfaces. <wrzasq>
* Uses IteratorAggregate interface instead of Iterator in some places (returns ArrayIterator as iterator). <wrzasq>
* __get()/__set() implementation. <wrzasq>
* __toString() as display drivers. <wrzasq>
* Additional wrappers for resource binds. <wrzasq>
* Some additional updates to match OTServ development. <wrzasq>
* Fixed some typos. <wrzasq>
* Code cleanup. <wrzasq>
[0.0.8]
* Added items.xml and items.otb files support. <wrzasq>
* Added Iterator and Countable interfaces implementation in OTS_OTBMFile class. <wrzasq>
* Fixed quoting guild rank name while updating. <wrzasq>
* Fixed custom fields reading in OTS_Guild class. <wrzasq>
[0.0.7]
* Updated for last database changes. <wrzasq>
* Even more PHP 5.0 compatibility. <wrzasq>
* Added spells support. <wrzasq>
* Added possibility to sort lists by custom fields, not only selected. <wrzasq>
* Fixed typos. <wrzasq>
[0.0.6]
* Updated for last database changes. <wrzasq>
* Increased PHP 5.0 compatibility. <wrzasq>
* Added generic binary formats reader with cache drivers. <wrzasq>
* Added OTBM files basic support. <wrzasq>
* Added monsters support. <wrzasq>
* Added OTS_Player::getVocationName() method. <wrzasq>
[0.0.5]
* Added support for vocations.xml file. <wrzasq>
* Added support for bans. <wrzasq>
* Added sorting and filtering for lists. <wrzasq>
* Code grouped into base classes. <wrzasq>
* Some code optimalisation. <wrzasq>
* Fixed typos. <wrzasq>
[0.0.4]
* Added guild system support (guilds, ranks, invitations and requests drivers mechanisms). <wrzasq>
* Added account group support. <wrzasq>
* Added support for depot_id field (it is reserverd in OTServ for futher use). <wrzasq>
* Added PostgreSQL and ODBC drivers. <wrzasq>
* Added __sleep() and __wakeup() methods to allow POT objects to be stored in sessions. <wrzasq>
* Added __clone() methods to allow save ID-losing cloning of POT objects. <wrzasq>
* Added __set_state() methods. <wrzasq>
* Updated players table structure. <wrzasq>
* Dropped REGEXP operator bindings - not used anywhere. <wrzasq>
* Fixed items loading and saving. <wrzasq>
* Fixed typos. <wrzasq>
[0.0.3]
* Added custom fields support. <wrzasq>
* Added items and depots support. <wrzasq>
* Added support for players PACC timestamps. <wrzasq>
* Fixed loading skills. <wrzasq>
* Replaced E_USER_* with exceptions. <wrzasq>
* Uses fetchAll() in loops to prevent MySQL buffering problems. <wrzasq>
* Restricted access to POT class constructor to make sure it won't be instanced directly. <wrzasq>
[0.0.2]
* Added "compat" library for POT. <wrzasq>
* Added skills support in OTS_Player class. <wrzasq>
* Added 'info' serverStatus() method and respond handler for server status protocol. <wrzasq>
* Fixed `redskulltime` field name in OTS_Player. <wrzasq>
* Fixed 'password' parameter for DB_MYSQL driver. <wrzasq>
* Added find() to OTS_Account class to load accounts by their's e-mail addresses. <wrzasq>
* POT class now automaticly binds own __autoload() handler with spl_autoload_register(). <wrzasq>
[0.0.1]
* Initial release. <wrzasq>

View File

@@ -0,0 +1,36 @@
<?php
/**#@+
* @version 0.1.2
* @since 0.0.6
*/
/**
* @package POT
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/
/**
* Generic exception class for error codes.
*
* @package POT
*/
class E_OTS_ErrorCode extends Exception
{
/**
* Sets error code.
*
* @param int $code Error code.
* @param string $message Optional error message.
*/
public function __construct($code, $message = '')
{
parent::__construct($message, $code);
}
}
/**#@-*/
?>

View File

@@ -0,0 +1,56 @@
<?php
/**#@+
* @version 0.0.6
* @since 0.0.6
*/
/**
* Code in this file bases on oryginal OTServ binary format loading C++ code (fileloader.h, fileloader.cpp).
*
* @package POT
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/
/**
* Error during reading OTServ binary file.
*
* @package POT
*/
class E_OTS_FileLoaderError extends E_OTS_ErrorCode
{
/**
* Unsupported file version.
*/
const ERROR_INVALID_FILE_VERSION = 1;
/**
* Could not open file.
*/
const ERROR_CAN_NOT_OPEN = 2;
/**
* Unexpected end of file.
*/
const ERROR_EOF = 4;
/**
* Failed to seek in given position in file.
*/
const ERROR_SEEK_ERROR = 5;
/**
* Attempted to execute operation on not opened file.
*/
const ERROR_NOT_OPEN = 6;
/**
* File corrupted.
*/
const ERROR_INVALID_FORMAT = 8;
/**
* Failed to read position in file.
*/
const ERROR_TELL_ERROR = 9;
}
/**#@-*/
?>

View File

@@ -0,0 +1,40 @@
<?php
/**#@+
* @version 0.1.1
* @since 0.1.1
*/
/**
* @package POT
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/
/**
* Generic exception class for general exceptions.
*
* @package POT
*/
class E_OTS_Generic extends E_OTS_ErrorCode
{
/**
* No database driver speciffied.
*/
const CONNECT_NO_DRIVER = 1;
/**
* Invalid database driver.
*/
const CONNECT_INVALID_DRIVER = 2;
/**
* No free account numbers to create account.
*
* @deprecated 0.1.5.+SVN This case won't be used anymore since we use named accounts now.
*/
const CREATE_ACCOUNT_IMPOSSIBLE = 3;
}
/**#@-*/
?>

View File

@@ -0,0 +1,26 @@
<?php
/**#@+
* @version 0.0.4
* @since 0.0.4
*/
/**
* @package POT
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/
/**
* Occurs when code attempts to execute driven action that has no assigned driver to handle it.
*
* @package POT
*/
class E_OTS_NoDriver extends Exception
{
}
/**#@-*/
?>

View File

@@ -0,0 +1,26 @@
<?php
/**#@+
* @version 0.1.0
* @since 0.1.0
*/
/**
* @package POT
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/
/**
* Occurs when in database item which is not a container contains sub-items.
*
* @package POT
*/
class E_OTS_NotAContainer extends Exception
{
}
/**#@-*/
?>

View File

@@ -0,0 +1,26 @@
<?php
/**#@+
* @version 0.0.3
* @since 0.0.3
*/
/**
* @package POT
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/
/**
* Occurs when code attempts to access property of not loaded object.
*
* @package POT
*/
class E_OTS_NotLoaded extends Exception
{
}
/**#@-*/
?>

View File

@@ -0,0 +1,36 @@
<?php
/**#@+
* @version 0.0.6
* @since 0.0.6
*/
/**
* Code in this file bases on oryginal OTServ OTBM format loading C++ code (iomapotbm.h, iomapotbm.cpp).
*
* @package POT
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/
/**
* OTBM map loading error.
*
* @package POT
*/
class E_OTS_OTBMError extends E_OTS_ErrorCode
{
/**
* Unsupported file version.
*/
const LOADMAPERROR_OUTDATEDHEADER = 3;
/**
* Unknown node type.
*/
const LOADMAPERROR_UNKNOWNNODETYPE = 8;
}
/**#@-*/
?>

View File

@@ -0,0 +1,28 @@
<?php
/**#@+
* @version 0.0.6
* @since 0.0.6
*/
/**
* Code in this file bases on oryginal OTServ binary format loading C++ code (fileloader.h, fileloader.cpp).
*
* @package POT
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/
/**
* Occurs when properties stream has ended and there is still read attempt.
*
* @package POT
*/
class E_OTS_OutOfBuffer extends Exception
{
}
/**#@-*/
?>

View File

@@ -0,0 +1,26 @@
<?php
/**#@+
* @version 0.1.0
* @since 0.1.0
*/
/**
* @package POT
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/
/**
* Occurs when code attempts to evaluate write operation on read-only object.
*
* @package POT
*/
class E_OTS_ReadOnly extends Exception
{
}
/**#@-*/
?>

5
system/libs/pot/INSTALL Normal file
View File

@@ -0,0 +1,5 @@
POT is a toolkit which means you don't literaly install it. You copy it's files and write code for it. All source files are located in classes/ subdirectory. Copy them to your script directory.
You can put main file - OTS.php in different directory then other files.
For information about how to include POT in your code see the documentation.

View File

@@ -0,0 +1,41 @@
<?php
/**#@+
* @version 0.1.2
* @since 0.1.2
*/
/**
* @package POT
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 - 2008 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/
/**
* Cypher encryption/decryption class interface.
*
* @package POT
*/
interface IOTS_Cipher
{
/**
* Ecnrypts message.
*
* @param string $message Message to be encrypted.
* @return string Encrypted message.
*/
public function encrypt($message);
/**
* Decrypts encrypted message.
*
* @param string $message Encrypted message.
* @return string Decrypted content.
*/
public function decrypt($message);
}
/**#@-*/
?>

View File

@@ -0,0 +1,24 @@
<?php
/**#@+
* @version 0.1.0
*/
/**
* @package POT
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/
/**
* @package POT
* @deprecated 0.1.0 This interface is not used anymore.
*/
interface IOTS_DAO
{
}
/**#@-*/
?>

View File

@@ -0,0 +1,24 @@
<?php
/**#@+
* @version 0.1.3
*/
/**
* @package POT
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 - 2008 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/
/**
* @package POT
* @deprecated 0.0.5 Don't rely on this interface - it is for backward compatibility only. Check PDO instance instead.
*/
interface IOTS_DB
{
}
/**#@-*/
?>

View File

@@ -0,0 +1,93 @@
<?php
/**#@+
* @version 0.1.3
* @since 0.1.3
*/
/**
* @package POT
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 - 2008 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/
/**
* Display interface for non-database resources.
*
* <p>
* This way you can define low-level part of display logic to bind templates directly with POT objects.
* </p>
*
* @package POT
*/
interface IOTS_DataDisplay
{
/**
* Displays house.
*
* @param OTS_House $house House to be displayed.
* @return string String representation.
*/
public function displayHouse(OTS_House $house);
/**
* Displays houses list.
*
* @param OTS_Houses_List $housesList List to be displayed.
* @return string String representation.
*/
public function displayHousesList(OTS_Houses_List $housesList);
/**
* Displays item types list.
*
* @param OTS_ItemsList $itemsList Items list to be displayed.
* @return string String representation.
*/
public function displayItemsList(OTS_ItemsList $itemsList);
/**
* Displays item type.
*
* @param OTS_ItemType $itemType Type information.
* @return string String representation.
*/
public function displayItemType(OTS_ItemType $itemType);
/**
* Displays monster.
*
* @param OTS_Monster $monster Monster to be displayed.
* @return string String representation.
*/
public function displayMonster(OTS_Monster $monster);
/**
* Displays monsters list.
*
* @param OTS_MonstersList $monstersList List to be displayed.
* @return string String representation.
*/
public function displayMonstersList(OTS_MonstersList $monstersList);
/**
* Displays OTBM map info.
*
* @param OTS_OTBMFile $map Map to be displayed.
* @return string String representation.
*/
public function displayOTBMMap(OTS_OTBMFile $map);
/**
* Displays spell information.
*
* @param OTS_Spell $spell Spell to be displayed.
* @return string String representation.
*/
public function displaySpell(OTS_Spell $spell);
/**
* Displays spells list.
*
* @param OTS_GuildRanks_List $spellsList List to be displayed.
* @return string String representation.
*/
public function displaySpellsList(OTS_SpellsList $spellsList);
}
/**#@-*/
?>

View File

@@ -0,0 +1,100 @@
<?php
/**#@+
* @version 0.1.0
* @since 0.1.0
*/
/**
* @package POT
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/
/**
* Display interface.
*
* <p>
* This way you can define low-level part of display logic to bind templates directly with POT objects.
* </p>
*
* @package POT
*/
interface IOTS_Display
{
/**
* Displays player.
*
* @param OTS_Player $player Player to be displayed.
* @return string String representation.
*/
public function displayPlayer(OTS_Player $player);
/**
* Displays players list.
*
* @param OTS_Players_List $playersList List to be displayed.
* @return string String representation.
*/
public function displayPlayersList(OTS_Players_List $playersList);
/**
* Displays account.
*
* @param OTS_Account $account Account to be displayed.
* @return string String representation.
*/
public function displayAccount(OTS_Account $account);
/**
* Displays accounts list.
*
* @param OTS_Accounts_List $accountsList List to be displayed.
* @return string String representation.
*/
public function displayAccountsList(OTS_Accounts_List $accountList);
/**
* Displays guild.
*
* @param OTS_Guild $guild Guild to be displayed.
* @return string String representation.
*/
public function displayGuild(OTS_Guild $guild);
/**
* Displays guilds list.
*
* @param OTS_Guilds_List $guildsList List to be displayed.
* @return string String representation.
*/
public function displayGuildsList(OTS_Guild_List $guildList);
/**
* Displays group.
*
* @param OTS_Group $group Group to be displayed.
* @return string String representation.
*/
public function displayGroup(OTS_Group $group);
/**
* Displays groups list.
*
* @param OTS_Groups_List $groupsList List to be displayed.
* @return string String representation.
*/
public function displayGroupsList(OTS_Groups_List $groupsList);
/**
* Displays rank.
*
* @param OTS_GuildRank $guildRank Rank to be displayed.
* @return string String representation.
*/
public function displayGuildRank(OTS_GuildRank $guildRank);
/**
* Displays guild ranks list.
*
* @param OTS_GuildRanks_List $guildRanksList List to be displayed.
* @return string String representation.
*/
public function displayGuildRanksList(OTS_GuildRanks_List $guildRanksList);
}
/**#@-*/
?>

View File

@@ -0,0 +1,43 @@
<?php
/**#@+
* @version 0.0.6
* @since 0.0.6
*/
/**
* @package POT
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
* @todo future: Add hasCache() instead of mixed result type in readCache().
*/
/**
* This interface describes binary files cache control drivers.
*
* @package POT
* @tutorial POT/Cache_drivers.pkg
* @example examples/cache.php cache.php
*/
interface IOTS_FileCache
{
/**
* Returns cache.
*
* @param string $md5 MD5 hash of file.
* @return OTS_FileNode|null Root node (null if file cache is not valid).
*/
public function readCache($md5);
/**
* Writes node cache.
*
* @param string $md5 MD5 checksum of current file.
* @param OTS_FileNode $root Root node of file which should be cached.
*/
public function writeCache($md5, OTS_FileNode $root);
}
/**#@-*/
?>

View File

@@ -0,0 +1,71 @@
<?php
/**#@+
* @version 0.0.4
* @since 0.0.4
*/
/**
* @package POT
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/
/**
* Guild action interface.
*
* <p>
* This insterface indicates that class can handle OTServ guild action.
* </p>
*
* <p>
* You can use it for example to handle invites or membership requests.
* </p>
*
* <p>
* If you want to serialise (for example save in session) your guild obejcts with assigned drivers you need to implement also __sleep() and __wakeup() methods in your drivers, as assigned drivers are also serialised.
* </p>
*
* @package POT
*/
interface IOTS_GuildAction
{
/**
* Objects are initialized with a guild that they are assigned to.
*
* It is recommeded that your implementations calls assignment functions of $guild to automaticly assign itself as action handler.
*
* @param OTS_Guild $guild Guild that this driver is assigned to.
*/
public function __construct(OTS_Guild $guild);
/**
* List of saved pending actions.
*
* @return array List of actions.
*/
public function listRequests();
/**
* Adds new request.
*
* @param OTS_Player $player Player which is object of request.
*/
public function addRequest(OTS_Player $player);
/**
* Deletes request.
*
* @param OTS_Player $player Player which is object of request.
*/
public function deleteRequest(OTS_Player $player);
/**
* Finalizes request.
*
* @param OTS_Player $player Player which is object of request.
*/
public function submitRequest(OTS_Player $player);
}
/**#@-*/
?>

View File

@@ -0,0 +1,42 @@
<?php
/**#@+
* @version 0.0.8
* @since 0.0.8
*/
/**
* @package POT
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
* @todo future: Add hasItems() instead of mixed result type in readItems().
*/
/**
* This interface defines items.xml cache handler as an standard file cache extender.
*
* @package POT
* @tutorial POT/Cache_drivers.pkg#interface.items
*/
interface IOTS_ItemsCache extends IOTS_FileCache
{
/**
* Returns cache.
*
* @param string $md5 MD5 hash of file.
* @return array|null List of items (null if file cache is not valid).
*/
public function readItems($md5);
/**
* Writes items cache.
*
* @param string $md5 MD5 checksum of current file.
* @param array $items List of items to be saved.
*/
public function writeItems($md5, $items);
}
/**#@-*/
?>

View File

@@ -0,0 +1,96 @@
<?php
/*
This file is part of OTSCMS (http://www.otscms.com/) project.
Copyright (C) 2005 - 2008 Wrzasq (wrzasq@gmail.com)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
POT guilds invites driver.
*/
class InvitesDriver implements IOTS_GuildAction
{
// assigned guild
private $guild;
// database
private $db;
// initializes driver
public function __construct(OTS_Guild $guild)
{
$this->guild = $guild;
$this->db = POT::getInstance()->getDBHandle();
$this->guild->invitesDriver = $this;
}
// returns all invited players to current guild
public function listRequests()
{
$invites = array();
foreach( $this->db->query('SELECT ' . $this->db->fieldName('player_id') . ' FROM ' . $this->db->tableName('guild_invites') . ' WHERE ' . $this->db->fieldName('guild_id') . ' = '.$this->db->quote($this->guild->id)) as $invite)
{
$player = new OTS_Player();
$player->load($invite['player_id']);
$invites[] = $player;
}
return $invites;
}
// invites player to current guild
public function addRequest(OTS_Player $player)
{
$this->db->query('INSERT INTO ' . $this->db->tableName('guild_invites') .' (' . $this->db->fieldName('player_id') . ', ' . $this->db->fieldName('guild_id') . ') VALUES ('.$this->db->quote($player->getId()).', '.$this->db->quote($this->guild->id).')');
}
// un-invites player
public function deleteRequest(OTS_Player $player)
{
$this->db->query('DELETE FROM ' . $this->db->tableName('guild_invites') . ' WHERE ' . $this->db->fieldName('player_id') . ' = '.$this->db->quote($player->getId()).' AND ' . $this->db->fieldName('guild_id') . ' = '.$this->db->quote($this->guild->id));
}
// commits invitation
public function submitRequest(OTS_Player $player)
{
$rank = null;
// finds normal member rank
foreach($this->guild as $guildRank)
{
if($guildRank->level == 1)
{
$rank = $guildRank;
break;
}
}
if(empty($rank)) {
$rank = new OTS_GuildRank();
$rank->setGuild($this->guild);
$rank->setName('New Members');
$rank->setLevel(1);
$rank->save();
}
$player->setRank($rank);
$player->save();
// clears invitation
$this->deleteRequest($player);
}
}
?>

165
system/libs/pot/LICENSE Normal file
View File

@@ -0,0 +1,165 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.

View File

@@ -0,0 +1,68 @@
--------------------------------------------------------------------
The PHP License, version 3.0
Copyright (c) 1999 - 2006 The PHP Group. All rights reserved.
--------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
modification, is permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The name "PHP" must not be used to endorse or promote products
derived from this software without prior written permission. For
written permission, please contact group@php.net.
4. Products derived from this software may not be called "PHP", nor
may "PHP" appear in their name, without prior written permission
from group@php.net. You may indicate that your software works in
conjunction with PHP by saying "Foo for PHP" instead of calling
it "PHP Foo" or "phpfoo"
5. The PHP Group may publish revised and/or new versions of the
license from time to time. Each version will be given a
distinguishing version number.
Once covered code has been published under a particular version
of the license, you may always continue to use it under the terms
of that version. You may also choose to use such covered code
under the terms of any subsequent version of the license
published by the PHP Group. No one other than the PHP Group has
the right to modify the terms applicable to covered code created
under this License.
6. Redistributions of any form whatsoever must retain the following
acknowledgment:
"This product includes PHP, freely available from
<http://www.php.net/>".
THIS SOFTWARE IS PROVIDED BY THE PHP DEVELOPMENT TEAM ``AS IS'' AND
ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PHP
DEVELOPMENT TEAM OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------
This software consists of voluntary contributions made by many
individuals on behalf of the PHP Group.
The PHP Group can be contacted via Email at group@php.net.
For more information on the PHP Group and the PHP project,
please see <http://www.php.net>.
This product includes the Zend Engine, freely available at
<http://www.zend.com>.

View File

@@ -0,0 +1,75 @@
--------------------------------------------------------------------
The PHP License, version 2.02
Copyright (c) 1999 - 2002 The PHP Group. All rights reserved.
--------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
modification, is permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
3. The name "PHP" must not be used to endorse or promote products
derived from this software without prior permission from the
PHP Group. This does not apply to add-on libraries or tools
that work in conjunction with PHP. In such a case the PHP
name may be used to indicate that the product supports PHP.
4. The PHP Group may publish revised and/or new versions of the
license from time to time. Each version will be given a
distinguishing version number.
Once covered code has been published under a particular version
of the license, you may always continue to use it under the
terms of that version. You may also choose to use such covered
code under the terms of any subsequent version of the license
published by the PHP Group. No one other than the PHP Group has
the right to modify the terms applicable to covered code created
under this License.
5. Redistributions of any form whatsoever must retain the following
acknowledgment:
"This product includes PHP, freely available from
http://www.php.net/".
6. The software incorporates the Zend Engine, a product of Zend
Technologies, Ltd. ("Zend"). The Zend Engine is licensed to the
PHP Association (pursuant to a grant from Zend that can be
found at http://www.php.net/license/ZendGrant/) for
distribution to you under this license agreement, only as a
part of PHP. In the event that you separate the Zend Engine
(or any portion thereof) from the rest of the software, or
modify the Zend Engine, or any portion thereof, your use of the
separated or modified Zend Engine software shall not be governed
by this license, and instead shall be governed by the license
set forth at http://www.zend.com/license/ZendLicense/.
THIS SOFTWARE IS PROVIDED BY THE PHP DEVELOPMENT TEAM ``AS IS'' AND
ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PHP
DEVELOPMENT TEAM OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------
This software consists of voluntary contributions made by many
individuals on behalf of the PHP Group.
The PHP Group can be contacted via Email at group@php.net.
For more information on the PHP Group and the PHP project,
please see <http://www.php.net>.

21
system/libs/pot/NEWS Normal file
View File

@@ -0,0 +1,21 @@
What's new in 0.1.4 version?
* Updated for last database changes.
As always POT provides most up-to-date interface for database.
* Updated OTAdmin implementation.
Support for new COMMAND_KICK call. It is now possible to kick given player from server.
* Binary information protocol support.
It is now possible to use binary information protocol, which in new version provides such useful featuers like online players list.
* Server status routines grouped.
All routines related to server infromation protocols (both XML-based and binary) are now grouped within OTS_ServerInfo class.
* Bigfixes.
Some bugfixes to previously implemented features like VIP list.

1712
system/libs/pot/OTS.php Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,59 @@
<?php
/**
* @package POT
* @version 0.1.5
* @since 0.1.5
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 - 2008 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/
/**
* OTServ account ban.
*
* @package POT
* @version 0.1.5
* @since 0.1.5
*/
class OTS_AccountBan extends OTS_Ban
{
/**
* Ban data.
*
* @var array
* @version 0.1.5
* @since 0.1.5
*/
private $data = array('type' => POT::BAN_ACCOUNT, 'param' => 0, 'active' => true, 'admin_id' => 0, 'comment' => '', 'reason' => 0);
/**
* Loads account ban with given id.
*
* @version 0.1.5
* @since 0.1.5
* @param int $id Ban ID.
* @throws PDOException On PDO operation error.
*/
public function load($id)
{
// SELECT query on database
$this->data = $this->db->query('SELECT ' . $this->db->fieldName('id') . ', ' . $this->db->fieldName('type') . ', ' . $this->db->fieldName('value') . ', ' . $this->db->fieldName('param') . ', ' . $this->db->fieldName('active') . ', ' . $this->db->fieldName('expires') . ', ' . $this->db->fieldName('added') . ', ' . $this->db->fieldName('admin_id') . ', ' . $this->db->fieldName('comment') . ', ' . $this->db->fieldName('reason') . ' FROM ' . $this->db->tableName('bans') . ' WHERE ' . $this->db->fieldName('type') . ' = ' . POT::BAN_ACCOUNT . ' AND ' . $this->db->fieldName('id') . ' = ' . (int) $id)->fetch();
}
/**
* Loads account ban by banned account ID.
*
* @version 0.1.5
* @since 0.1.5
* @param int $id Account's ID.
* @throws PDOException On PDO operation error.
*/
public function find($id)
{
// SELECT query on database
$this->data = $this->db->query('SELECT ' . $this->db->fieldName('id') . ', ' . $this->db->fieldName('type') . ', ' . $this->db->fieldName('value') . ', ' . $this->db->fieldName('param') . ', ' . $this->db->fieldName('active') . ', ' . $this->db->fieldName('expires') . ', ' . $this->db->fieldName('added') . ', ' . $this->db->fieldName('admin_id') . ', ' . $this->db->fieldName('comment') . ', ' . $this->db->fieldName('reason') . ' FROM ' . $this->db->tableName('bans') . ' WHERE ' . $this->db->fieldName('type') . ' = ' . POT::BAN_ACCOUNT . ' AND ' . $this->db->fieldName('value') . ' = ' . (int) $id)->fetch();
}
}
?>

View File

@@ -0,0 +1,38 @@
<?php
/**
* @package POT
* @version 0.1.5
* @since 0.1.5
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 - 2008 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/
/**
* List of account bans.
*
* @package POT
* @version 0.1.5
* @since 0.1.5
*/
class OTS_AccountBans_List extends OTS_Bans_List
{
/**
* Initializes list with account bans filtering.
*
* @version 0.1.5
* @since 0.1.5
*/
public function __construct()
{
parent::__construct();
// filters only account bans
$filter = new OTS_SQLFilter();
$filter->addFilter( new OTS_SQLField('type', 'bans'), POT::BAN_ACCOUNT);
$this->setFilter($filter);
}
}
?>

View File

@@ -0,0 +1,70 @@
<?php
/**
* @package POT
* @version 0.1.3
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 - 2008 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/
/**
* List of accounts.
*
* @package POT
* @version 0.1.3
*/
class OTS_Accounts_List extends OTS_Base_List
{
/**
* @version 0.0.5
* @param OTS_Account $account Account to be deleted.
* @deprecated 0.0.5 Use OTS_Account->delete().
*/
public function deleteAccount(OTS_Account $account)
{
$this->db->query('DELETE FROM ' . $this->db->tableName('account') . ' WHERE ' . $this->db->fieldName('id') . ' = ' . $account->getId() );
}
/**
* Sets list parameters.
*
* <p>
* This method is called at object creation.
* </p>
*
* @version 0.0.5
* @since 0.0.5
*/
public function init()
{
$this->table = 'accounts';
$this->class = 'Account';
}
/**
* Returns string representation of object.
*
* <p>
* If any display driver is currently loaded then it uses it's method.
* </p>
*
* @version 0.1.3
* @since 0.1.0
* @return string String representation of object.
*/
public function __toString()
{
$ots = POT::getInstance();
// checks if display driver is loaded
if( $ots->isDisplayDriverLoaded() )
{
return $ots->getDisplayDriver()->displayAccountsList($this);
}
return (string) $this->count();
}
}
?>

View File

@@ -0,0 +1,739 @@
<?php
/**#@+
* @version 0.1.2
* @since 0.1.2
*/
/**
* @package POT
* @version 0.1.4
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 - 2008 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/
/**
* OTAdmin protocol client.
*
* @package POT
* @version 0.1.4
* @property-read bool $requiresLogin {@link OTS_Admin::requiresLogin() requiresLogin()} wrapper.
* @property-read bool $requiresEncryption {@link OTS_Admin::requiresEncryption() requiresEncryption()} wrapper.
* @property-read bool $usesRSA1024XTEA {@link OTS_Admin::usesRSA1024XTEA() usesRSA1024XTEA()} wrapper.
* @property-read int $ping Ping time.
* @property-write string $login Logs in with given password.
* @property-write string $broadcast Sends given broadcast message.
* @property-write string $kick Kicks player with given name from server.
* @tutorial POT/OTAdmin.pkg
* @example examples/admin.php admin.php
*/
class OTS_Admin
{
/**
* User login.
*/
const REQUEST_LOGIN = 1;
/**
* Encryption packet.
*/
const REQUEST_ENCRYPTION = 2;
/**
* RSA key exchange.
*/
const REQUEST_KEY_EXCHANGE = 3;
/**
* OTAdmin commnd.
*/
const REQUEST_COMMAND = 4;
/**
* Ping.
*/
const REQUEST_PING = 5;
/**
* Hello respond.
*/
const RESPOND_HELLO = 1;
/**
* Keys exchange success.
*/
const RESPOND_KEY_EXCHANGE_OK = 2;
/**
* Keys exchange failed.
*/
const RESPOND_KEY_EXCHANGE_FAILED = 3;
/**
* Login success.
*/
const RESPOND_LOGIN_OK = 4;
/**
* Login incorrect.
*/
const RESPOND_LOGIN_FAILED = 5;
/**
* Command success.
*/
const RESPOND_COMMAND_OK = 6;
/**
* Command failed.
*/
const RESPOND_COMMAND_FAILED = 7;
/**
* Encryption initialization success.
*/
const RESPOND_ENCRYPTION_OK = 8;
/**
* Encryption initialization failed.
*/
const RESPOND_ENCRYPTION_FAILED = 9;
/**
* Ping success.
*/
const RESPOND_PING_OK = 10;
/**
* Message.
*/
const RESPOND_MESSAGE = 11;
/**
* Error.
*/
const RESPOND_ERROR = 12;
/**
* Broadcast message.
*/
const COMMAND_BROADCAST = 1;
/**
* Closes server.
*/
const COMMAND_CLOSE_SERVER = 2;
/**
* Pays all rented shouses.
*/
const COMMAND_PAY_HOUSES = 3;
/**
* Not supported in current OTAdmin imlpementation.
*/
const COMMAND_OPEN_SERVER = 4;
/**
* Shutdowns the server.
*/
const COMMAND_SHUTDOWN_SERVER = 5;
/**
* Not supported in current OTAdmin imlpementation.
*/
const COMMAND_RELOAD_SCRIPTS = 6;
/**
* Not supported in current OTAdmin imlpementation.
*/
const COMMAND_PLAYER_INFO = 7;
/**
* Not supported in current OTAdmin imlpementation.
*/
const COMMAND_GETONLINE = 8;
/**
* Not supported in current OTAdmin imlpementation.
*/
const COMMAND_KICK = 9;
/**
* Not supported in current OTAdmin imlpementation.
*/
const COMMAND_BAN_MANAGER = 10;
/**
* Not supported in current OTAdmin imlpementation.
*/
const COMMAND_SERVER_INFO = 11;
/**
* Not supported in current OTAdmin imlpementation.
*/
const COMMAND_GETHOUSE = 12;
/**
* Server requires login.
*/
const REQUIRE_LOGIN = 1;
/**
* Server requires encryption.
*/
const REQUIRE_ENCRYPTION = 2;
/**
* Server uses XTEA encryption, XTEA key is being sent in 1024bit RSA encrypted packet.
*/
const ENCRYPTION_RSA1024XTEA = 1;
/**
* Socket handle.
*
* @var resource
*/
private $socket;
/**
* Server security policy.
*
* @var int
*/
private $policy;
/**
* Protocol options.
*
* @var int
*/
private $options;
/**
* Packets cipher.
*
* @var IOTS_Cipher
*/
private $cipher;
/**
* Host address for session sleep/wakeup.
*
* @var string
*/
private $host;
/**
* Port number for session sleep/wakeup.
*
* @var int
*/
private $port;
/**
* Creates new connection to OTServ administration backend.
*
* <p>
* This method automaticly handles RSA and XTEA encryption if such method is required by server including keys negotiations.
* </p>
*
* <p>
* After connecting you should check {@link OTS_Admin::requiresLogin() if server requires login}.
* </p>
*
* @param string $host Target server.
* @param int $port Port (7171 by default).
* @throws E_OTS_ErrorCode When receive failed respond or unexpected message.
* @throws E_OTS_OutOfBuffer When there is read attemp after end of packet stream.
*/
public function __construct($host, $port = 7171)
{
// saves connection sessint
$this->host = $host;
$this->port = $port;
// opens connection
$this->socket = fsockopen($this->host, $this->port);
// 254 = OTAdmin protocol identifier
$message = new OTS_Buffer( chr(254) );
// sends initial packet
$respond = $this->send($message);
$message->reset();
$byte = $respond->getChar();
// checks if it's HELLO packet
if($byte != self::RESPOND_HELLO)
{
throw new E_OTS_ErrorCode($byte);
}
// skips respond signature and protocol version
$respond->getLong();
$respond->getString();
// saves protocol settings
$this->policy = $respond->getShort();
$this->options = $respond->getLong();
// handles encryption initialisation if required
if( $this->requiresEncryption() && $this->usesRSA1024XTEA() )
{
// requests public key
$message->putChar(self::REQUEST_KEY_EXCHANGE);
$message->putChar(self::ENCRYPTION_RSA1024XTEA);
$respond = $this->send($message);
$message->reset();
$byte = $respond->getChar();
// checks if it succeded
if($byte != self::RESPOND_KEY_EXCHANGE_OK)
{
throw new E_OTS_ErrorCode($byte, $respond->getString() );
}
// we support only RSA 1024bit encryption for XTEA key sending
if( $respond->getChar() != self::ENCRYPTION_RSA1024XTEA)
{
throw new E_OTS_ErrorCode($byte);
}
// reads binary form of public key (128 bytes)
$key = OTS_BinaryTools::bin2Int( strrev( $respond->getString(128) ) );
// creates RSA cipher
// as we have ready N computer here and we don't compute it by ourselves we can use a little hack, to save N as P * Q we will use P = N and Q = 1
$rsa = new OTS_RSA($key, '1');
$key = '';
// generates random XTEA key
for($i = 0; $i < 4; $i++)
{
$key .= pack('L', rand(0, 4294967295) );
}
$xtea = new OTS_XTEA($key);
// sends XTEA key
$message->putChar(self::REQUEST_ENCRYPTION);
$message->putChar(self::ENCRYPTION_RSA1024XTEA);
$message->putString( $rsa->encrypt( chr(0) . $key), false);
// we can't bind cipher yet since only respnd will be XTEA encrypted
$respond = new OTS_Buffer( $xtea->decrypt( $this->send($message)->getBuffer() ) );
$byte = $respond->getChar();
// checks if encryption negotation succeeded
if($byte != self::RESPOND_ENCRYPTION_OK)
{
throw new E_OTS_ErrorCode($byte, $respond->getString());
}
// saves encryption/decryption cipher
$this->cipher = $xtea;
}
}
/**
* Checks if protocol requires login.
*
* @return bool True if protocol requires user login.
*/
public function requiresLogin()
{
return ($this->policy & self::REQUIRE_LOGIN) == self::REQUIRE_LOGIN;
}
/**
* Checks if protocol requires encryption.
*
* @return bool True if protocol requires encryption.
*/
public function requiresEncryption()
{
return ($this->policy & self::REQUIRE_ENCRYPTION) == self::REQUIRE_ENCRYPTION;
}
/**
* Checks if protocol requires XTEA encryption with RSA-encrypted key.
*
* @return bool True if protocol requires that encryption.
*/
public function usesRSA1024XTEA()
{
return ($this->options & self::ENCRYPTION_RSA1024XTEA) == self::ENCRYPTION_RSA1024XTEA;
}
/**
* Sends OTAdmin packet.
*
* @param OTS_Buffer $message Packet to be sent.
* @return OTS_Buffer Server respond.
* @throws E_OTS_ErrorCode When receive RESPOND_ERROR message.
* @throws E_OTS_OutOfBuffer When there is read attemp after end of packet stream.
*/
public function send(OTS_Buffer $message)
{
$message = $message->getBuffer();
// encrypts message if required
if( isset($this->cipher) )
{
$message = $this->cipher->encrypt($message);
}
$message = pack('v', strlen($message) ) . $message;
fputs($this->socket, $message);
// reads respond length
$length = unpack('v', fgets($this->socket, 3) );
$buffer = fgets($this->socket, $length[1] + 1);
// decrypts buffer if required
if( isset($this->cipher) )
{
$buffer = $this->cipher->decrypt($buffer);
}
// checks for error code
$respond = new OTS_Buffer($buffer);
if( $respond->getChar() == self::RESPOND_ERROR)
{
throw new E_OTS_ErrorCode(self::RESPOND_ERROR, $respond->getString() );
}
// returns respond
$respond->setPos(0);
return $respond;
}
/**
* Closes connection.
*/
public function __destruct()
{
fclose($this->socket);
}
/**
* Magic PHP5 method.
*
* @version 0.1.3
* @since 0.1.3
* @param string $name Property name.
* @param mixed $value Property value.
* @throws OutOfBoundsException For non-supported properties.
* @throws E_OTS_ErrorCode When receive failed respond or unexpected message.
* @throws E_OTS_OutOfBuffer When there is read attemp after end of packet stream.
*/
public function __get($name)
{
switch($name)
{
case 'requiresLogin':
return $this->requiresLogin();
case 'requiresEncryption':
return $this->requiresEncryption();
case 'usesRSA1024XTEA':
return $this->usesRSA1024XTEA();
case 'ping':
return $this->ping();
default:
throw new OutOfBoundsException();
}
}
/**
* Magic PHP5 method.
*
* @version 0.1.4
* @since 0.1.3
* @param string $name Property name.
* @param mixed $value Property value.
* @throws OutOfBoundsException For non-supported properties.
* @throws E_OTS_ErrorCode When receive failed respond or unexpected message.
* @throws E_OTS_OutOfBuffer When there is read attemp after end of packet stream.
*/
public function __set($name, $value)
{
switch($name)
{
case 'login':
$this->login($value);
break;
case 'broadcast':
$this->broadcast($value);
break;
case 'kick':
$this->kick($value);
break;
default:
throw new OutOfBoundsException();
}
}
/**
* Logs into server.
*
* <p>
* Call this method if after connection is established login required flag is set.
* </p>
*
* @param string $password Admin password.
* @throws E_OTS_ErrorCode When receive failed respond or unexpected message.
* @throws E_OTS_OutOfBuffer When there is read attemp after end of packet stream.
*/
public function login($password)
{
// password packet
$message = new OTS_Buffer();
$message->putChar(self::REQUEST_LOGIN);
$message->putString($password);
// reads respond
$message = $this->send($message);
$byte = $message->getChar();
// checks respond
if($byte != self::RESPOND_LOGIN_OK)
{
throw new E_OTS_ErrorCode($byte, $message->getString());
}
}
/**
* Ping command.
*
* <p>
* Note: This methods calculates ping time based on {@link OTS_Admin::send() OTS_Admin::send()} sub-call. This means ping time will be time used for entire seding operation including packet encryption, packing, unpacking and decryption.
* </p>
*
* @return int Ping time.
* @throws E_OTS_ErrorCode When receive failed respond or unexpected message.
* @throws E_OTS_OutOfBuffer When there is read attemp after end of packet stream.
*/
public function ping()
{
// constructs message
$message = new OTS_Buffer();
$message->putChar(self::REQUEST_PING);
// start
$ping = microtime(true);
$message = $this->send($message);
// stop
$ping = microtime(true) - $ping;
$byte = $message->getChar();
// checks if command succeeded
if($byte != self::RESPOND_PING_OK)
{
throw new E_OTS_ErrorCode($byte, $respond->getString());
}
return $ping;
}
/**
* Sends command message.
*
* <p>
* This method wraps another buffer within command byte and also checks for command success.
* </p>
*
* @param OTS_Buffer $message Command to be send.
* @return OTS_Buffer Respond.
* @throws E_OTS_ErrorCode If failure respond received.
* @throws E_OTS_OutOfBuffer When there is read attemp after end of packet stream.
*/
private function sendCommand(OTS_Buffer $message)
{
// prepends command byte
$buffer = new OTS_Buffer();
$buffer->putChar(self::REQUEST_COMMAND);
$buffer->putString( $message->getBuffer(), false);
// sends command
$buffer = $this->send($buffer);
$byte = $buffer->getChar();
// checks for error code
if($byte != self::RESPOND_COMMAND_OK)
{
throw new E_OTS_ErrorCode($byte, $buffer->getString() );
}
// returns respond with reseted position
$buffer->setPos(0);
return $buffer;
}
/**
* Sends COMMAND_BROADCAST command with given parameter.
*
* <p>
* Sends broadcast message to all players.
* </p>
*
* @param string $message Broadcast to be sent.
* @throws E_OTS_ErrorCode If failure respond received.
* @throws E_OTS_OutOfBuffer When there is read attemp after end of packet stream.
*/
public function broadcast($message)
{
// sends message
$buffer = new OTS_Buffer();
$buffer->putChar(self::COMMAND_BROADCAST);
$buffer->putString($message);
$this->sendCommand($buffer);
}
/**
* Sends COMMAND_CLOSE_SERVER command.
*
* <p>
* Closes server. This command closes server for connections to enable maintenance but doesn't shut it down.
* </p>
*
* @throws E_OTS_ErrorCode If failure respond received.
* @throws E_OTS_OutOfBuffer When there is read attemp after end of packet stream.
*/
public function close()
{
// sends message
$buffer = new OTS_Buffer();
$buffer->putChar(self::COMMAND_CLOSE_SERVER);
$this->sendCommand($buffer);
}
public function open()
{
// sends message
$buffer = new OTS_Buffer();
$buffer->putChar(self::COMMAND_OPEN_SERVER);
$this->sendCommand($buffer);
}
public function reloadScripts($type)
{
// sends message
$buffer = new OTS_Buffer();
$buffer->putChar(self::COMMAND_RELOAD_SCRIPTS);
$buffer->putChar($type);
$this->sendCommand($buffer);
}
/**
* Sends COMMAND_PAY_HOUSES command.
*
* <p>
* Takes fees for all rented houses.
* </p>
*
* @throws E_OTS_ErrorCode If failure respond received.
* @throws E_OTS_OutOfBuffer When there is read attemp after end of packet stream.
*/
public function payHouses()
{
// sends message
$buffer = new OTS_Buffer();
$buffer->putChar(self::COMMAND_PAY_HOUSES);
$this->sendCommand($buffer);
}
/**
* Sends COMMAND_SHUTDOWN_SERVER command.
*
* <p>
* Shutdowns server. This command closes server thread.
* </p>
*
* @throws E_OTS_ErrorCode If failure respond received.
* @throws E_OTS_OutOfBuffer When there is read attemp after end of packet stream.
*/
public function shutdown()
{
// sends message
$buffer = new OTS_Buffer();
$buffer->putChar(self::COMMAND_SHUTDOWN_SERVER);
$this->sendCommand($buffer);
}
/**
* Sends COMMAND_KICK command with given parameter.
*
* <p>
* Kicks given player from server.
* </p>
*
* @version 0.1.4
* @since 0.1.4
* @param string $name Name of player to be kicked.
* @throws E_OTS_ErrorCode If failure respond received.
* @throws E_OTS_OutOfBuffer When there is read attemp after end of packet stream.
*/
public function kick($name)
{
// sends message
$buffer = new OTS_Buffer();
$buffer->putChar(self::COMMAND_KICK);
$buffer->putString($name);
$this->sendCommand($buffer);
}
/**
* Magic PHP5 method.
*
* <p>
* Allows object importing from {@link http://www.php.net/manual/en/function.var-export.php var_export()}.
* </p>
*
* @param array $properties List of object properties.
* @throws E_OTS_ErrorCode When receive failed respond or unexpected message.
* @throws E_OTS_OutOfBuffer When there is read attemp after end of packet stream.
*/
public static function __set_state($properties)
{
return new self($properties['host'], $properties['port']);
}
/**
* Magic PHP5 method.
*
* <p>
* Creates new socket connection to server.
* </p>
*
* @throws E_OTS_ErrorCode When receive failed respond or unexpected message.
* @throws E_OTS_OutOfBuffer When there is read attemp after end of packet stream.
*/
public function __clone()
{
$this->__construct($this->host, $this->port);
}
/**
* Magic PHP5 method.
*
* <p>
* Allows object serialisation.
* </p>
*
* @return array List of properties that should be saved.
*/
public function __sleep()
{
return array('host', 'port');
}
/**
* Magic PHP5 method.
*
* <p>
* Allows object unserialisation.
* </p>
*
* @throws E_OTS_ErrorCode When receive failed respond or unexpected message.
* @throws E_OTS_OutOfBuffer When there is read attemp after end of packet stream.
*/
public function __wakeup()
{
$this->__construct($this->host, $this->port);
}
}
/**#@-*/
?>

597
system/libs/pot/OTS_Ban.php Normal file
View File

@@ -0,0 +1,597 @@
<?php
/**
* @package POT
* @version 0.1.5
* @since 0.1.5
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 - 2008 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/
/**
* OTServ ban generic class. For particular purpose use {@link OTS_AccountBan OTS_AccountBan}, {@link OTS_PlayerBan OTS_PlayerBan} or {@link OTS_IPBan OTS_IPBan} classes respectively.
*
* @package POT
* @version 0.1.5
* @since 0.1.5
* @property int $value Banned target identifier.
* @property int $param Additional parameter (usualy IP mask).
* @property bool $active Activation state.
* @property int $expires Expiration time.
* @property int $added Creation time.
* @property int $adminId ID of admin who created ban.
* @property string $command Additional comment.
* @property int $reason Reason identifier.
* @property-read bool $loaded Loaded state check.
* @property-read int $id Row ID.
*/
abstract class OTS_Ban extends OTS_Row_DAO
{
/**
* Ban data.
*
* @var array
* @version 0.1.5
* @since 0.1.5
*/
private $data = array('param' => 0, 'active' => true, 'admin_id' => 0, 'comment' => '', 'reason' => 0);
/**
* Loads ban with given id.
*
* @version 0.1.5
* @since 0.1.5
* @param int $id Ban ID.
* @throws PDOException On PDO operation error.
*/
public function load($id)
{
// SELECT query on database
$this->data = $this->db->query('SELECT ' . $this->db->fieldName('id') . ', ' . $this->db->fieldName('type') . ', ' . $this->db->fieldName('value') . ', ' . $this->db->fieldName('param') . ', ' . $this->db->fieldName('active') . ', ' . $this->db->fieldName('expires') . ', ' . $this->db->fieldName('added') . ', ' . $this->db->fieldName('admin_id') . ', ' . $this->db->fieldName('comment') . ', ' . $this->db->fieldName('reason') . ' FROM ' . $this->db->tableName('bans') . ' WHERE ' . $this->db->fieldName('id') . ' = ' . (int) $id)->fetch();
}
/**
* Checks if object is loaded.
*
* @version 0.1.5
* @since 0.1.5
* @return bool Load state.
*/
public function isLoaded()
{
return isset($this->data['id']);
}
/**
* Saves ban in database.
*
* <p>
* If object is not loaded to represent any existing ban it will create new row for it.
* </p>
*
* @version 0.1.5
* @since 0.1.5
* @throws PDOException On PDO operation error.
*/
public function save()
{
// updates existing ban
if( isset($this->data['id']) )
{
// UPDATE query on database
$this->db->query('UPDATE ' . $this->db->tableName('bans') . ' SET ' . $this->db->fieldName('type') . ' = ' . $this->data['type'] . ', ' . $this->db->fieldName('value') . ' = ' . $this->data['value'] . ', ' . $this->db->fieldName('param') . ' = ' . $this->data['param'] . ', ' . $this->db->fieldName('active') . ' = ' . (int) $this->data['active'] . ', ' . $this->db->fieldName('expires') . ' = ' . $this->data['expires'] . ', ' . $this->db->fieldName('added') . ' = ' . $this->data['added'] . ', ' . $this->db->fieldName('admin_id') . ' = ' . $this->data['admin_id'] . ', ' . $this->db->fieldName('comment') . ' = ' . $this->db->quote($this->data['comment']) . ', ' . $this->db->fieldName('reason') . ' = ' . $this->data['reason'] . ' WHERE ' . $this->db->fieldName('id') . ' = ' . $this->data['id']);
}
// creates new ban
else
{
// INSERT query on database
$this->db->query('INSERT INTO ' . $this->db->tableName('bans') . ' (' . $this->db->fieldName('type') . ', ' . $this->db->fieldName('value') . ', ' . $this->db->fieldName('param') . ', ' . $this->db->fieldName('active') . ', ' . $this->db->fieldName('expires') . ', ' . $this->db->fieldName('added') . ', ' . $this->db->fieldName('admin_id') . ', ' . $this->db->fieldName('comment') . ', ' . $this->db->fieldName('reason') . ') VALUES (' . $this->data['type'] . ', ' . $this->data['value'] . ', ' . $this->data['param'] . ', ' . (int) $this->data['active'] . ', ' . $this->data['expires'] . ', ' . $this->data['added'] . ', ' . $this->data['admin_id'] . ', ' . $this->db->quote($this->data['comment']) . ', ' . $this->data['reason'] . ')');
// ID of new ban
$this->data['id'] = $this->db->lastInsertId();
}
}
/**
* Ban ID.
*
* @version 0.1.5
* @since 0.1.5
* @return int Ban ID.
* @throws E_OTS_NotLoaded If ban is not loaded.
*/
public function getId()
{
if( !isset($this->data['id']) )
{
throw new E_OTS_NotLoaded();
}
return $this->data['id'];
}
/**
* Deletes ban.
*
* @version 0.1.5
* @since 0.1.5
* @throws E_OTS_NotLoaded If ban is not loaded.
* @throws PDOException On PDO operation error.
*/
public function delete()
{
if( !isset($this->data['id']) )
{
throw new E_OTS_NotLoaded();
}
// deletes row from database
$this->db->query('DELETE FROM ' . $this->db->tableName('bans') . ' WHERE ' . $this->db->fieldName('id') . ' = ' . $this->data['id']);
// resets object handle
unset($this->data['id']);
}
/**
* Banned target.
*
* @version 0.1.5
* @since 0.1.5
* @return int Target identifier.
* @throws E_OTS_NotLoaded If ban is not loaded.
*/
public function getValue()
{
if( !isset($this->data['value']) )
{
throw new E_OTS_NotLoaded();
}
return $this->data['value'];
}
/**
* Sets banned target.
*
* <p>
* This method only updates object state. To save changes in database you need to use {@link OTS_Ban::save() save() method} to flush changed to database.
* </p>
*
* @version 0.1.5
* @since 0.1.5
* @param int $value Banned target identifier.
*/
public function setValue($value)
{
$this->data['value'] = (int) $value;
}
/**
* Additional parameter.
*
* @version 0.1.5
* @since 0.1.5
* @return int Parameter value (usualy used as IP mask).
* @throws E_OTS_NotLoaded If ban is not loaded.
*/
public function getParam()
{
if( !isset($this->data['param']) )
{
throw new E_OTS_NotLoaded();
}
return $this->data['param'];
}
/**
* Sets additional parameter.
*
* <p>
* This method only updates object state. To save changes in database you need to use {@link OTS_Ban::save() save() method} to flush changed to database.
* </p>
*
* @version 0.1.5
* @since 0.1.5
* @param int $param Parameter value (usualy used as IP mask).
*/
public function setParam($param)
{
$this->data['param'] = (int) $param;
}
/**
* Activation state.
*
* @version 0.1.5
* @since 0.1.5
* @return bool Is ban active.
* @throws E_OTS_NotLoaded If ban is not loaded.
*/
public function isActive()
{
if( !isset($this->data['active']) )
{
throw new E_OTS_NotLoaded();
}
return $this->data['active'];
}
/**
* Activates ban.
*
* <p>
* This method only updates object state. To save changes in database you need to use {@link OTS_Ban::save() save() method} to flush changed to database.
* </p>
*
* @version 0.1.5
* @since 0.1.5
*/
public function activate()
{
$this->data['active'] = true;
}
/**
* Deactivates ban.
*
* <p>
* This method only updates object state. To save changes in database you need to use {@link OTS_Ban::save() save() method} to flush changed to database.
* </p>
*
* @version 0.1.5
* @since 0.1.5
*/
public function deactivate()
{
$this->data['active'] = false;
}
/**
* Expiration time.
*
* @version 0.1.5
* @since 0.1.5
* @return int Ban expiration time (0 - forever).
* @throws E_OTS_NotLoaded If ban is not loaded.
*/
public function getExpires()
{
if( !isset($this->data['expires']) )
{
throw new E_OTS_NotLoaded();
}
return $this->data['expires'];
}
/**
* Sets expiration time.
*
* <p>
* This method only updates object state. To save changes in database you need to use {@link OTS_Ban::save() save() method} to flush changed to database.
* </p>
*
* @version 0.1.5
* @since 0.1.5
* @param int $expires Ban expiration time (0 - forever).
*/
public function setExpires($expires)
{
$this->data['expires'] = (int) $expires;
}
/**
* Banned time.
*
* @version 0.1.5
* @since 0.1.5
* @return int Ban creation time.
* @throws E_OTS_NotLoaded If ban is not loaded.
*/
public function getAdded()
{
if( !isset($this->data['added']) )
{
throw new E_OTS_NotLoaded();
}
return $this->data['added'];
}
/**
* Sets banned time.
*
* <p>
* This method only updates object state. To save changes in database you need to use {@link OTS_Ban::save() save() method} to flush changed to database.
* </p>
*
* @version 0.1.5
* @since 0.1.5
* @param int $added Ban creation time.
*/
public function setAdded($added)
{
$this->data['added'] = (int) $added;
}
/**
* Ban creator.
*
* @version 0.1.5
* @since 0.1.5
* @return int ID of administrator who created ban entry.
* @throws E_OTS_NotLoaded If ban is not loaded.
*/
public function getAdminId()
{
if( !isset($this->data['admin_id']) )
{
throw new E_OTS_NotLoaded();
}
return $this->data['admin_id'];
}
/**
* Sets ban creator.
*
* <p>
* This method only updates object state. To save changes in database you need to use {@link OTS_Ban::save() save() method} to flush changed to database.
* </p>
*
* @version 0.1.5
* @since 0.1.5
* @param int $adminId ID of administrator who created ban entry.
*/
public function setAdminId($adminId)
{
$this->data['admin_id'] = (int) $adminId;
}
/**
* Explaination comment.
*
* @version 0.1.5
* @since 0.1.5
* @return string Ban description.
* @throws E_OTS_NotLoaded If ban is not loaded.
*/
public function getComment()
{
if( !isset($this->data['comment']) )
{
throw new E_OTS_NotLoaded();
}
return $this->data['comment'];
}
/**
* Sets explaination comment.
*
* <p>
* This method only updates object state. To save changes in database you need to use {@link OTS_Ban::save() save() method} to flush changed to database.
* </p>
*
* @version 0.1.5
* @since 0.1.5
* @param string $comment Ban description.
*/
public function setComment($comment)
{
$this->data['comment'] = (string) $comment;
}
/**
* Ban reason.
*
* @version 0.1.5
* @since 0.1.5
* @return int Reason for which ban was created.
* @throws E_OTS_NotLoaded If ban is not loaded.
*/
public function getReason()
{
if( !isset($this->data['reason']) )
{
throw new E_OTS_NotLoaded();
}
return $this->data['reason'];
}
/**
* Sets ban reason.
*
* <p>
* This method only updates object state. To save changes in database you need to use {@link OTS_Ban::save() save() method} to flush changed to database.
* </p>
*
* @version 0.1.5
* @since 0.1.5
* @param int $reason Reason for which ban was created.
*/
public function setReason($reason)
{
$this->data['reason'] = (int) $reason;
}
/**
* Reads custom field.
*
* <p>
* Reads field by it's name. Can read any field of given record that exists in database.
* </p>
*
* <p>
* Note: You should use this method only for fields that are not provided in standard setters/getters (SVN fields). This method runs SQL query each time you call it so it highly overloads used resources.
* </p>
*
* @version 0.1.5
* @since 0.1.5
* @param string $field Field name.
* @return string Field value.
* @throws E_OTS_NotLoaded If ban is not loaded.
* @throws PDOException On PDO operation error.
*/
public function getCustomField($field)
{
if( !isset($this->data['id']) )
{
throw new E_OTS_NotLoaded();
}
$value = $this->db->query('SELECT ' . $this->db->fieldName($field) . ' FROM ' . $this->db->tableName('bans') . ' WHERE ' . $this->db->fieldName('id') . ' = ' . $this->data['id'])->fetch();
return $value[$field];
}
/**
* Writes custom field.
*
* <p>
* Write field by it's name. Can write any field of given record that exists in database.
* </p>
*
* <p>
* Note: You should use this method only for fields that are not provided in standard setters/getters (SVN fields). This method runs SQL query each time you call it so it highly overloads used resources.
* </p>
*
* <p>
* Note: Make sure that you pass $value argument of correct type. This method determinates whether to quote field name. It is safe - it makes you sure that no unproper queries that could lead to SQL injection will be executed, but it can make your code working wrong way. For example: $object->setCustomField('foo', '1'); will quote 1 as as string ('1') instead of passing it as a integer.
* </p>
*
* @version 0.1.5
* @since 0.1.5
* @param string $field Field name.
* @param mixed $value Field value.
* @throws E_OTS_NotLoaded If account is not loaded.
* @throws PDOException On PDO operation error.
*/
public function setCustomField($field, $value)
{
if( !isset($this->data['id']) )
{
throw new E_OTS_NotLoaded();
}
// quotes value for SQL query
if(!( is_int($value) || is_float($value) ))
{
$value = $this->db->quote($value);
}
$this->db->query('UPDATE ' . $this->db->tableName('bans') . ' SET ' . $this->db->fieldName($field) . ' = ' . $value . ' WHERE ' . $this->db->fieldName('id') . ' = ' . $this->data['id']);
}
/**
* Magic PHP5 method.
*
* @version 0.1.5
* @since 0.1.5
* @param string $name Property name.
* @return mixed Property value.
* @throws E_OTS_NotLoaded If ban is not loaded.
* @throws OutOfBoundsException For non-supported properties.
* @throws PDOException On PDO operation error.
*/
public function __get($name)
{
switch($name)
{
case 'loaded':
return $this->isLoaded();
case 'id':
return $this->getId();
case 'value':
return $this->getValue();
case 'param':
return $this->getParam();
case 'active':
return $this->isActive();
case 'expires':
return $this->getExpires();
case 'added':
return $this->getAdded();
case 'adminId':
return $this->getAdminId();
case 'comment':
return $this->getComment();
case 'reason':
return $this->getReason();
default:
throw new OutOfBoundsException();
}
}
/**
* Magic PHP5 method.
*
* @version 0.1.5
* @since 0.1.5
* @param string $name Property name.
* @param mixed $value Property value.
* @throws OutOfBoundsException For non-supported properties.
* @throws PDOException On PDO operation error.
*/
public function __set($name, $value)
{
switch($name)
{
case 'value':
$this->setValue($value);
break;
case 'param':
$this->setParam($value);
break;
case 'active':
if($value)
{
$this->activate();
}
else
{
$this->deactivate();
}
break;
case 'expires':
$this->setExpires($value);
break;
case 'added':
$this->setAdded($value);
break;
case 'adminId':
$this->setAdminId($value);
break;
case 'comment':
$this->setComment($value);
break;
case 'reason':
$this->setReason($value);
break;
default:
throw new OutOfBoundsException();
}
}
}
?>

View File

@@ -0,0 +1,104 @@
<?php
/**
* @package POT
* @version 0.1.5
* @since 0.1.5
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 - 2008 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/
/**
* List of all bans.
*
* @package POT
* @version 0.1.5
* @since 0.1.5
*/
class OTS_Bans_List extends OTS_Base_List
{
/**
* Sets list parameters.
*
* <p>
* This method is called at object creation.
* </p>
*
* @version 0.1.5
* @since 0.1.5
*/
public function init()
{
$this->table = 'bans';
}
/**
* Overwrites generic query.
*
* @version 0.1.5
* @since 0.1.5
* @throws PDOException On PDO operation error.
*/
public function rewind()
{
$this->rows = $this->db->query( $this->getSQL() )->fetchAll();
}
/**
* Returns SQL query for SELECT.
*
* @version 0.1.5
* @since 0.1.5
* @param bool $count Shows if the SQL should be generated for COUNT() variant.
* @return string SQL query part.
*/
protected function getSQL($count = false)
{
$fields = array();
// fields list
if($count)
{
$fields[] = 'COUNT(' . $this->db->tableName($this->table) . '.' . $this->db->fieldName('id') . ')';
}
else
{
$fields[] = $this->db->tableName('bans') . '.' . $this->db->fieldName('id') . ' AS ' . $this->db->fieldName('id');
$fields[] = $this->db->tableName('bans') . '.' . $this->db->fieldName('type') . ' AS ' . $this->db->fieldName('type');
}
return $this->prepareSQL($fields);
}
/**
* Returns current row.
*
* <p>
* Returns object of class which handle single row representation. Object is initialised with ID of current position in result cursor.
* </p>
*
* @version 0.1.5
* @since 0.1.5
* @return OTS_Ban Current row.
*/
public function current()
{
$row = current($this->rows);
// selects correct class
switch($row['type'])
{
case POT::BAN_IP:
return new OTS_IPBan( (int) $id['id']);
case POT::BAN_ACCOUNT:
return new OTS_AccountBan( (int) $id['id']);
case POT::BAN_PLAYER:
return new OTS_PlayerBan( (int) $id['id']);
}
}
}
?>

View File

@@ -0,0 +1,120 @@
<?php
/**#@+
* @version 0.0.5
* @since 0.0.5
*/
/**
* @package POT
* @version 0.1.0
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/
/**
* Basic data access object routines.
*
* <p>
* This class defines basic mechanisms for all classes that will represent database accessors. However no coding logic is defined here - only connection handling and PHP core-related stuff to enable variouse operations with objects.
* </p>
*
* <p>
* This class is mostly usefull when you create own extensions for POT code.
* </p>
*
* @package POT
* @version 0.1.0
*/
abstract class OTS_Base_DAO implements IOTS_DAO
{
/**
* Database connection.
*
* @var PDO
*/
protected $db;
/**
* Sets database connection handler.
*
* @version 0.1.0
*/
public function __construct()
{
$this->db = POT::getInstance()->getDBHandle();
}
/**
* Magic PHP5 method.
*
* <p>
* Allows object serialisation.
* </p>
*
* @return array List of properties that should be saved.
*/
public function __sleep()
{
return array('data');
}
/**
* Magic PHP5 method.
*
* <p>
* Allows object unserialisation.
* </p>
*/
public function __wakeup()
{
$this->db = POT::getInstance()->getDBHandle();
}
/**
* Creates clone of object.
*
* <p>
* Copy of object needs to have different ID.
* </p>
*/
public function __clone()
{
unset($this->data['id']);
}
/**
* Magic PHP5 method.
*
* <p>
* Allows object importing from {@link http://www.php.net/manual/en/function.var-export.php var_export()}.
* </p>
*
* @version 0.1.0
* @param array $properties List of object properties.
*/
public static function __set_state($properties)
{
// deletes database handle
if( isset($properties['db']) )
{
unset($properties['db']);
}
// initializes new object with current database connection
$object = new self();
// loads properties
foreach($properties as $name => $value)
{
$object->$name = $value;
}
return $object;
}
}
/**#@-*/
?>

View File

@@ -0,0 +1,241 @@
<?php
/**#@+
* @version 0.1.3
* @since 0.1.3
*/
/**
* @package POT
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/
/**
* Base class for all database drivers.
*
* <p>
* It defines additional rotines required by database driver for POT using default SQL standard-compliant method.
* </p>
*
* @package POT
*/
abstract class OTS_Base_DB extends PDO implements IOTS_DB
{
/**
* Tables prefix.
*
* @var string
*/
private $prefix = '';
/**
* Query counter
*
* @var int
*/
private $queries = 0;
/**
* Query-quoted field name.
*
* @param string $name Field name.
* @return string Quoted name.
*/
public function fieldName($name)
{
return '"' . $name . '"';
}
public function fieldNames()
{
$ret = '';
$argc = func_num_args();
$argv = func_get_args();
for($i = 0; $i < $argc; $i++) {
$ret .= $this->fieldName($argv[$i]) . ',';
}
$ret[strlen($ret) - 1] = '';
return $ret;
}
/**
* Query-quoted table name.
*
* @param string $name Table name.
* @return string Quoted name.
*/
public function tableName($name)
{
return $this->fieldName($this->prefix . $name);
}
/**
* @param stirng $string String to be quoted.
* @return string Quoted string.
* @deprecated 0.0.5 Use PDO::quote().
* @version 0.0.7
*/
public function SQLquote($string)
{
return parent::quote($string, PDO_PARAM_STR);
}
/**
* @param string $query SQL query.
* @return PDOStatement|bool Query results.
* @deprecated 0.0.5 Use PDO::query().
*/
public function SQLquery($query)
{
return query($query);
}
public function query($query)
{
$this->queries++;
return parent::query($query);
}
public function select($table, $data)
{
$fields = array_keys($data);
$values = array_values($data);
$query = 'SELECT * FROM ' . $this->tableName($table) . ' WHERE (';
for ($i = 0; $i < count($fields); $i++)
$query.= $this->fieldName($fields[$i]).' = '.$this->quote($values[$i]).' AND ';
$query = substr($query, 0, strlen($query)-4);
$query.=');';
$query = $this->query($query);
if($query->rowCount() != 1) return false;
return $query->fetch();
}
public function insert($table, $data)
{
$fields = array_keys($data);
$values = array_values($data);
$query = 'INSERT INTO ' . $this->tableName($table) . ' (';
foreach ($fields as $field)
$query.= $this->fieldName($field).',';
$query = substr($query, 0, strlen($query) - 1);
$query .= ') VALUES (';
foreach ($values as $value)
if ($value === null)
$query .= 'NULL,';
else
$query .= $this->quote($value).',';
$query = substr($query, 0, strlen($query) - 1);
$query .= ')';
$this->query($query);
return true;
}
public function replace($table, $data)
{
$fields = array_keys($data);
$values = array_values($data);
$query = 'REPLACE INTO '.$this->tableName($table).' (';
foreach ($fields as $field)
$query.= $this->fieldName($field).',';
$query = substr($query, 0, strlen($query) - 1);
$query.= ') VALUES (';
foreach ($values as $value)
if ($value === null)
$query.= 'NULL,';
else
$query.= $this->quote($value).',';
$query = substr($query, 0, strlen($query) - 1);
$query .= ')';
$this->query($query);
return true;
}
public function update($table, $data, $where, $limit = 1)
{
$fields = array_keys($data);
$values = array_values($data);
$query = 'UPDATE '.$this->tableName($table).' SET ';
for ($i = 0; $i < count($fields); $i++)
$query.= $this->fieldName($fields[$i]).' = '.$this->quote($values[$i]).', ';
$query = substr($query, 0, strlen($query)-2);
$query.=' WHERE (';
$fields = array_keys($where);
$values = array_values($where);
for ($i = 0; $i < count($fields); $i++)
$query.= $this->fieldName($fields[$i]).' = '.$this->quote($values[$i]).' AND ';
$query = substr($query, 0, strlen($query)-4);
if (isset($limit))
$query .=') LIMIT '.$limit.';';
else
$query .=');';
$this->query($query);
return true;
}
public function delete($table, $data, $limit = 1)
{
$fields = array_keys($data);
$values = array_values($data);
$query = 'DELETE FROM ' . $this->tableName($table) . ' WHERE (';
for ($i = 0; $i < count($fields); $i++)
$query .= $this->fieldName($fields[$i]) . ' = ' . $this->quote($values[$i]) . ' AND ';
$query = substr($query, 0, strlen($query) - 4);
if ($limit > 0)
$query.=') LIMIT '.$limit.';';
else
$query.=');';
$this->query($query);
return true;
}
/**
* LIMIT/OFFSET clause for queries.
*
* @param int|bool $limit Limit of rows to be affected by query (false if no limit).
* @param int|bool $offset Number of rows to be skipped before applying query effects (false if no offset).
* @return string LIMIT/OFFSET SQL clause for query.
*/
public function limit($limit = false, $offset = false)
{
// by default this is empty part
$sql = '';
if($limit !== false)
{
$sql = ' LIMIT ' . $limit;
// OFFSET has no effect if there is no LIMIT
if($offset !== false)
{
$sql .= ' OFFSET ' . $offset;
}
}
return $sql;
}
public function queries() {
return $this->queries;
}
}
/**#@-*/
?>

View File

@@ -0,0 +1,466 @@
<?php
/**#@+
* @version 0.0.5
* @since 0.0.5
*/
/**
* @package POT
* @version 0.1.5
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 - 2008 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
* @todo future: Use fetchObject() to reduce amount of SQL queries.
* @todo future: Iterator classes (to map id => name iterations) with tutorial.
*/
/**
* Basic list class routines.
*
* <p>
* This class defines entire lists mechanism for classes that represents records set from OTServ database. All child classes only have to define {@link OTS_Base_List::init() init() method} to set table info for queries.
* </p>
*
* <p>
* Table on which list will operate has to contain integer <var>"id"</var> field and single row representing class has to support loading by this filed as key.
* </p>
*
* <p>
* This class is mostly usefull when you create own extensions for POT code.
* </p>
*
* @package POT
* @version 0.1.5
* @property-write int $limit Sets LIMIT clause.
* @property-write int $offset Sets OFFSET clause.
* @property-write OTS_SQLFilter $filter Sets filter for list SQL query.
*/
abstract class OTS_Base_List implements IOTS_DAO, Iterator, Countable
{
/**
* Database connection.
*
* @var PDO
* @version 0.1.5
*/
protected $db;
/**
* Limit for SELECT query.
*
* @var int
*/
private $limit = false;
/**
* Offset for SELECT query.
*
* @var int
*/
private $offset = false;
/**
* WHERE clause filter.
*
* @var OTS_SQLFilter
*/
private $filter = null;
/**
* List of sorting criteriums.
*
* @var array
*/
private $orderBy = array();
/**
* Query results.
*
* @var array
* @version 0.1.5
*/
protected $rows;
/**
* Default table name for queries.
*
* @var string
*/
protected $table;
/**
* Class of generated objects.
*
* @var string
*/
protected $class;
/**
* Sets database connection handler.
*
* @version 0.1.0
*/
public function __construct()
{
$this->db = POT::getInstance()->getDBHandle();
$this->init();
}
/**
* Sets list parameters.
*/
abstract public function init();
/**
* Magic PHP5 method.
*
* <p>
* Allows object serialisation.
* </p>
*
* @return array List of properties that should be saved.
*/
public function __sleep()
{
return array('limit', 'offset', 'filter', 'orderBy', 'table', 'class');
}
/**
* Magic PHP5 method.
*
* <p>
* Allows object unserialisation.
* </p>
*/
public function __wakeup()
{
$this->db = POT::getInstance()->getDBHandle();
}
/**
* Magic PHP5 method.
*
* <p>
* Allows object importing from {@link http://www.php.net/manual/en/function.var-export.php var_export()}.
* </p>
*
* @version 0.1.3
* @param array $properties List of object properties.
*/
public static function __set_state($properties)
{
// deletes database handle
if( isset($properties['db']) )
{
unset($properties['db']);
}
// initializes new object with current database connection
$object = new self();
// loads properties
foreach($properties as $name => $value)
{
$object->$name = $value;
}
return $object;
}
/**
* Sets LIMIT clause.
*
* <p>
* Reduces amount of seleced rows up to given number.
* </p>
*
* @param int|bool $limit Limit for SELECT (false to reset).
*/
public function setLimit($limit = false)
{
if( is_int($limit) )
{
$this->limit = $limit;
}
else
{
$this->limit = false;
}
}
/**
* Sets OFFSET clause.
*
* <p>
* Moves starting rows of selected set to given position.
* </p>
*
* @param int|bool $offset Offset for SELECT (false to reset).
*/
public function setOffset($offset = false)
{
if( is_int($offset) )
{
$this->offset = $offset;
}
else
{
$this->offset = false;
}
}
/**
* Returns current row.
*
* <p>
* Returns object of class which handle single row representation. Object is initialised with ID of current position in result cursor.
* </p>
*
* @version 0.1.3
* @return OTS_Base_DAO Current row.
*/
public function current()
{
$id = current($this->rows);
$class = 'OTS_' . $this->class;
return new $class( (int) $id['id']);
}
/**
* Select rows from database.
*
* @throws PDOException On PDO operation error.
*/
public function rewind()
{
$this->rows = $this->db->query( $this->getSQL() )->fetchAll();
}
/**
* Moves to next row.
*/
public function next()
{
next($this->rows);
}
/**
* Current cursor position.
*
* @return mixed Array key.
*/
public function key()
{
return key($this->rows);
}
/**
* Checks if there are any rows left.
*
* @return bool Does next row exist.
*/
public function valid()
{
return key($this->rows) !== null;
}
/**
* Returns number of rows on list in current criterium.
*
* @version 0.1.5
* @return int Number of rows.
* @throws PDOException On PDO operation error.
*/
public function count()
{
return $this->db->query( $this->getSQL(true) )->fetchColumn();
}
/**
* Sets filter on list.
*
* <p>
* Call without argument to reset filter.
* </p>
*
* @param OTS_SQLFilter|null $filter Filter for list.
*/
public function setFilter(OTS_SQLFilter $filter = null)
{
$this->filter = $filter;
}
/**
* Clears ORDER BY clause.
*/
public function resetOrder()
{
$this->orderBy = array();
}
/**
* Appends sorting rule.
*
* <p>
* First parameter may be of type string, then it will be used as literal field name, or object of {@link OTS_SQLField OTS_SQLField class}, then it's representation will be used as qualiffied SQL identifier name.
* </p>
*
* <p>
* Note: Since 0.0.7 version <var>$field</var> parameter can be instance of {@link OTS_SQLField OTS_SQLField class}.
* </p>
*
* @version 0.0.7
* @param OTS_SQLField|string $field Field name.
* @param int $order Sorting order (ascending by default).
*/
public function orderBy($field, $order = POT::ORDER_ASC)
{
// constructs field name filter
if($field instanceof OTS_SQLField)
{
$table = $field->getTable();
// full table name
if( !empty($table) )
{
$table = $this->db->tableName($table) . '.';
}
$field = $table . $this->db->fieldName( $field->getName() );
}
// literal name
else
{
$field = $this->db->fieldName($field);
}
$this->orderBy[] = array('field' => $field, 'order' => $order);
}
/**
* Returns SQL query for SELECT.
*
* @version 0.1.5
* @param bool $count Shows if the SQL should be generated for COUNT() variant.
* @return string SQL query part.
*/
protected function getSQL($count = false)
{
// fields list
if($count)
{
$fields = 'COUNT(' . $this->db->tableName($this->table) . '.' . $this->db->fieldName('id') . ')';
}
else
{
$fields = $this->db->tableName($this->table) . '.' . $this->db->fieldName('id') . ' AS ' . $this->db->fieldName('id');
}
return $this->prepareSQL( array($fields) );
}
/**
* Returns generic SQL query that can be adaptated by child classes.
*
* @version 0.1.5
* @since 0.1.5
* @param array $fields Fields to be selected.
* @return string SQL query.
*/
protected function prepareSQL($fields)
{
$tables = array();
// generates tables list for current qeury
if( isset($this->filter) )
{
$tables = $this->filter->getTables();
}
// adds default table
if( !in_array($this->table, $tables) )
{
$tables[] = $this->table;
}
// prepares tables names
foreach($tables as &$name)
{
$name = $this->db->tableName($name);
}
// WHERE clause
if( isset($this->filter) )
{
$where = ' WHERE ' . $this->filter->__toString();
}
else
{
$where = '';
}
// ORDER BY clause
if(isset($count) || empty($this->orderBy) )
{
$orderBy = '';
}
else
{
$orderBy = array();
foreach($this->orderBy as $criterium)
{
switch($criterium['order'])
{
case POT::ORDER_ASC:
$orderBy[] = $criterium['field'] . ' ASC';
break;
case POT::ORDER_DESC:
$orderBy[] = $criterium['field'] . ' DESC';
break;
}
}
$orderBy = ' ORDER BY ' . implode(', ', $orderBy);
}
return 'SELECT ' . implode(', ', $fields) . ' FROM ' . implode(', ', $tables) . $where . $orderBy . $this->db->limit($this->limit, $this->offset);
}
/**
* Magic PHP5 method.
*
* @version 0.1.0
* @since 0.1.0
* @param string $name Property name.
* @param mixed $value Property value.
* @throws OutOfBoundsException For non-supported properties.
*/
public function __set($name, $value)
{
switch($name)
{
case 'limit':
$this->setLimit($value);
break;
case 'offset':
$this->setOffset($value);
break;
case 'filter':
$this->setFilter($value);
break;
default:
throw new OutOfBoundsException();
}
}
}
/**#@-*/
?>

View File

@@ -0,0 +1,150 @@
<?php
/**#@+
* @version 0.1.2
* @since 0.1.2
*/
/**
* @package POT
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 - 2008 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/
/**
* This is class similar to {@link OTS_Toolbox OTS_Toolbox} except that this class contains routines for binary number operations. It is mainly used by encryption/decryption classes so you are probably not interested in using it.
*
* @package POT
*/
class OTS_BinaryTools
{
/**
* Handle proper unsigned right shift, dealing with PHP's signed shift.
*
* @param int $integer Number to be shifted.
* @param int $n Number of bits to shift.
* @return int Shifted integer.
*/
public static function unsignedRightShift($integer, $n)
{
// convert to 32 bits
if(0xFFFFFFFF < $integer || -0xFFFFFFFF > $integer)
{
$integer = fmod($integer, 0xFFFFFFFF + 1);
}
// convert to unsigned integer
if(0x7FFFFFFF < $integer)
{
$integer -= 0xFFFFFFFF + 1;
}
elseif(-0x80000000 > $integer)
{
$integer += 0xFFFFFFFF + 1;
}
// do right shift
if (0 > $integer)
{
// remove sign bit before shift
$integer &= 0x7FFFFFFF;
// right shift
$integer >>= $n;
// set shifted sign bit
$integer |= 1 << (31 - $n);
}
else
{
// use normal right shift
$integer >>= $n;
}
return $integer;
}
/**
* Handle proper unsigned add, dealing with PHP's signed add.
*
* @param int $a First number.
* @param int $b Second number.
* @return int Unsigned sum.
*/
public static function unsignedAdd($a, $b)
{
// remove sign if necessary
if($a < 0)
{
$a -= 1 + 0xFFFFFFFF;
}
if($b < 0)
{
$b -= 1 + 0xFFFFFFFF;
}
$result = $a + $b;
// convert to 32 bits
if(0xFFFFFFFF < $result || -0xFFFFFFFF > $result)
{
$result = fmod($result, 0xFFFFFFFF + 1);
}
// convert to signed integer
if(0x7FFFFFFF < $result)
{
$result -= 0xFFFFFFFF + 1;
}
elseif(-0x80000000 > $result)
{
$result += 0xFFFFFFFF + 1;
}
return $result;
}
/**
* Transforms binary representation of large integer into string.
*
* @param string $string Binary string.
* @return string Numeric representation.
*/
public static function bin2Int($string)
{
$result = '0';
$n = strlen($string);
do
{
$result = bcadd( bcmul($result, '256'), ord($string[--$n]) );
}
while($n > 0);
return $result;
}
/**
* Transforms large integer into binary string.
*
* @param string $number Large integer.
* @return string Binary string.
*/
public static function int2Bin($number)
{
$result = '';
do
{
$result .= chr( bcmod($number, '256') );
$number = bcdiv($number, '256');
}
while( bccomp($number, '0') );
return $result;
}
}
/**#@-*/
?>

View File

@@ -0,0 +1,421 @@
<?php
/**#@+
* @version 0.1.2
* @since 0.1.2
*/
/**
* @package POT
* @version 0.1.3
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 - 2008 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/
/**
* Binary buffer container.
*
* <p>
* This is generic class for classes that uses buffer-baser read-write operations (it can also emulate C-like pointers).
* <p>
*
* <p>
* Note that unlike <var>NetworkMessage</var> class from OTServ C++ source code, in this one reading and writing positions are separated so you can pararelly read and write it's content like for example using object of this class as stack.
* </p>
*
* @package POT
* @version 0.1.3
* @property string $buffer Properties binary string.
* @property int $char {@link OTS_Buffer::getChar() getChar()}/{@link OTS_Buffer::putChar() putChar()} method wrapper.
* @property int $short {@link OTS_Buffer::getShort() getShort()}/{@link OTS_Buffer::putShort() putShort()} method wrapper.
* @property int $long {@link OTS_Buffer::getLong() getLong()}/{@link OTS_Buffer::putLong() putLong()} method wrapper.
* @property string $string {@link OTS_Buffer::getString() getString(false)}/{@link OTS_Buffer::putString() putString(, true)} call wrapper.
* @property int $pos {@link OTS_Buffer::getPos() getPos()}/{@link OTS_Buffer::setPos() setPos()} method wrapper.
* @property-read bool $valid {@link OTS_Buffer::isValid() isValid()} method wrapper.
* @property-read int $size {@link OTS_Buffer::getSize() getSize()} method wrapper.
*/
class OTS_Buffer
{
/**
* Node properties stream.
*
* @var string
*/
protected $buffer;
/**
* Properties stream pointer.
*
* @var int
*/
protected $pos;
/**
* Initializes new buffered reader.
*
* @param string $buffer Buffer content.
*/
public function __construct($buffer = '')
{
$this->buffer = $buffer;
$this->pos = 0;
}
/**
* Magic PHP5 method.
*
* <p>
* Allows object importing from {@link http://www.php.net/manual/en/function.var-export.php var_export()}.
* </p>
*
* @param array $properties List of object properties.
*/
public static function __set_state($properties)
{
$object = new self();
// loads properties
foreach($properties as $name => $value)
{
$object->$name = $value;
}
return $object;
}
/**
* Returs properties stream.
*
* @return string Properties stream.
*/
public function getBuffer()
{
return $this->buffer;
}
/**
* Sets properties stream.
*
* @param string Properties stream.
*/
public function setBuffer($buffer)
{
$this->buffer = $buffer;
$this->pos = 0;
}
/**
* Checks if there is anything left in stream.
*
* @return bool False if pointer is at the end of stream.
*/
public function isValid()
{
return $this->pos < strlen($this->buffer);
}
/**
* Checks stream end state.
*
* @param int $size Amount of bytes that are going to be read.
* @throws E_OTS_OutOfBuffer When there is read attemp after end of stream.
*/
protected function check($size = 1)
{
if( strlen($this->buffer) < $this->pos + $size)
{
throw new E_OTS_OutOfBuffer();
}
}
/**
* Returns single byte.
*
* @return int Byte (char) value.
* @throws E_OTS_OutOfBuffer When there is read attemp after end of stream.
*/
public function getChar()
{
// checks buffer size
$this->check();
$value = ord($this->buffer[$this->pos]);
$this->pos++;
return $value;
}
/**
* Appends single byte to buffer.
*
* @param int $char Byte (char) value.
*/
public function putChar($char)
{
$this->buffer .= chr($char);
}
/**
* Returns double byte.
*
* @return int Word (short) value.
* @throws E_OTS_OutOfBuffer When there is read attemp after end of stream.
*/
public function getShort()
{
// checks buffer size
$this->check(2);
$value = unpack('v', substr($this->buffer, $this->pos, 2) );
$this->pos += 2;
return $value[1];
}
/**
* Appends double byte to buffer.
*
* @param int $short Word (short) value.
*/
public function putShort($short)
{
$this->buffer .= pack('v', $short);
}
/**
* Returns quater byte.
*
* @return int Double word (long) value.
* @throws E_OTS_OutOfBuffer When there is read attemp after end of stream.
*/
public function getLong()
{
// checks buffer size
$this->check(4);
$value = unpack('V', substr($this->buffer, $this->pos, 4) );
$this->pos += 4;
return $value[1];
}
/**
* Appends quater byte to buffer.
*
* @param int $long Double word (long) value.
*/
public function putLong($long)
{
$this->buffer .= pack('V', $long);
}
/**
* Returns string from buffer.
*
* <p>
* If length is not given then treats first short value from current buffer as string length.
* </p>
*
* @param int|bool $length String length.
* @return string First substring.
* @throws E_OTS_OutOfBuffer When there is read attemp after end of stream.
*/
public function getString($length = false)
{
// reads string length if not given
if($length === false)
{
$length = $this->getShort();
}
// checks buffer size
$this->check($length);
// copies substring
$value = substr($this->buffer, $this->pos, $length);
$this->pos += $length;
return $value;
}
/**
* Appends string to buffer.
*
* @param string $string Binary length.
* @param bool $dynamic Whether if string length is fixed or not (if it is dynamic then length will be inserted as short before string chunk).
*/
public function putString($string, $dynamic = true)
{
// appends string length if requires
if($dynamic)
{
$this->putShort( strlen($string) );
}
$this->buffer .= $string;
}
/**
* Empties buffer.
*/
public function reset()
{
$this->__construct();
}
/**
* Returns current read position.
*
* @return int Read position.
*/
public function getPos()
{
return $this->pos;
}
/**
* Seeks current reading position.
*
* @param int $pos Read position.
*/
public function setPos($pos)
{
$this->pos = $pos;
}
/**
* Returns buffer size.
*
* @return int Buffer length.
*/
public function getSize()
{
return strlen($this->buffer);
}
/**
* Skips given amount of bytes.
*
* @param int $n Bytes to skip.
* @throws E_OTS_OutOfBuffer When there is read attemp after end of stream.
*/
public function skip($n)
{
$this->check($n);
$this->pos += $n;
}
/**
* Magic PHP5 method.
*
* @param string $name Property name.
* @return mixed Property value.
* @throws OutOfBoundsException For non-supported properties.
* @throws E_OTS_OutOfBuffer When there is read attemp after end of stream.
*/
public function __get($name)
{
switch($name)
{
// simple properties
case 'buffer':
return $this->buffer;
// isValid() wrapper
case 'valid':
return $this->isValid();
// getChar() wrapper
case 'char':
return $this->getChar();
// getShort() wrapper
case 'short':
return $this->getShort();
// getLong() wrapper
case 'long':
return $this->getLong();
// getString() wrapper
case 'string':
return $this->getString();
// getPos() wrapper
case 'pos':
return $this->getPos();
// getSize() wrapper
case 'size':
return $this->getSize();
default:
throw new OutOfBoundsException();
}
}
/**
* Magic PHP5 method.
*
* @version 0.1.3
* @param string $name Property name.
* @param mixed $value Property value.
* @throws OutOfBoundsException For non-supported properties.
*/
public function __set($name, $value)
{
switch($name)
{
// buffer needs to be reset
case 'buffer':
$this->setBuffer($value);
break;
// putChar() wrapper
case 'char':
$this->putChar($value);
break;
// putShort() wrapper
case 'short':
$this->putShort($value);
break;
// putLong() wrapper
case 'long':
$this->putLong($value);
break;
// putString() wrapper
case 'string':
$this->putString($value);
break;
// setPos() wrapper
case 'pos':
$this->setPos($value);
break;
default:
throw new OutOfBoundsException();
}
}
/**
* Returns string representation of buffer object.
*
* @return string Object's buffer.
*/
public function __toString()
{
return $this->buffer;
}
/**
* Resets pointer of cloned object.
*/
public function __clone()
{
$this->pos = 0;
}
}
/**#@-*/
?>

View File

@@ -0,0 +1,153 @@
<?php
/**#@+
* @version 0.0.3
* @since 0.0.3
*/
/**
* @package POT
* @version 0.1.3
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/
/**
* Container item representation.
*
* <p>
* This class represents items that can contain other items. It's {@link OTS_Container::count() count() method} has been overwritten so it now doesn't return count of current item (if it would even be possible for containers) but amount of items within (not recursively).
* </p>
*
* @package POT
* @version 0.1.3
*/
class OTS_Container extends OTS_Item implements IteratorAggregate
{
/**
* Contained items.
*
* @var array
*/
private $items = array();
/**
* Adds item to container.
*
* @param OTS_Item $item Item.
*/
public function addItem(OTS_Item $item)
{
$this->items[] = $item;
}
/**
* Removes given item from current container.
*
* <p>
* Passed item must be exacly instance of item which is stored in container, not it's copy. This method bases on PHP references.
* </p>
*
* @param OTS_Item $item Item.
* @tutorial POT/Players.pkg#deleting
*/
public function removeItem(OTS_Item $item)
{
foreach($this->items as $index => $current)
{
// checks if it is EXACLY the same item, not similar
if($item === $current)
{
unset($this->items[$index]);
}
}
}
/**
* Number of items inside container.
*
* <p>
* OTS_Container implementation of Countable interface differs from {@link OTS_Item OTS_Item} implemention. {@link OTS_Item::count() OTS_Item::count()} returns count of given item, OTS_Container::count() returns number of items inside container. If somehow it would be possible to make container items with more then 1 in one place, you can use {@link OTS_Item::getCount() OTS_Item::getCount()} and {@link OTS_Item::setCount() OTS_Item::setCount()} in code where you are not sure if working with regular item, or container.
* </p>
*
* @return int Number of items.
*/
public function count()
{
return count($items);
}
/**
* @return OTS_Item Current item.
* @deprecated 0.1.0 Use getIterator().
*/
public function current()
{
return current($this->items);
}
/**
* @deprecated 0.1.0 Use getIterator().
*/
public function next()
{
next($this->items);
}
/**
* @return mixed Iterator position.
* @deprecated 0.1.0 Use getIterator().
*/
public function key()
{
return key($this->items);
}
/**
* @return bool Does next item exist.
* @deprecated 0.1.0 Use getIterator().
*/
public function valid()
{
return key($this->items) !== null;
}
/**
* @deprecated 0.1.0 Use getIterator().
*/
public function rewind()
{
reset($this->items);
}
/**
* Returns iterator handle for loops.
*
* @version 0.1.0
* @since 0.1.0
* @return ArrayIterator Items iterator.
*/
public function getIterator()
{
return new ArrayIterator($this->items);
}
/**
* Clones all contained items.
*
* @version 0.1.3
* @since 0.1.3
*/
public function __clone()
{
foreach($this->items as $index => $item)
{
$this->items[$index] = clone $item;
}
}
}
/**#@-*/
?>

View File

@@ -0,0 +1,149 @@
<?php
/**#@+
* @version 0.0.1
*/
/**
* @package POT
* @version 0.1.3
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/
/**
* MySQL connection interface.
*
* <p>
* At all everything that you really need to read from this class documentation is list of parameters for driver's constructor.
* </p>
*
* @package POT
* @version 0.1.3
*/
class OTS_DB_MySQL extends OTS_Base_DB
{
/**
* Creates database connection.
*
* <p>
* Connects to MySQL database on given arguments.
* </p>
*
* <p>
* List of parameters for this drivers:
* </p>
*
* <ul>
* <li><var>host</var> - database server.</li>
* <li><var>port</var> - port (optional, also it is possible to use host:port in <var>host</var> parameter).</li>
* <li><var>database</var> - database name.</li>
* <li><var>user</var> - user login.</li>
* <li><var>password</var> - user password.</li>
* </ul>
*
* @version 0.0.6
* @param array $params Connection parameters.
* @throws PDOException On PDO operation error.
*/
public function __construct($params)
{
$user = null;
$password = null;
$dns = array();
// host:port support
if( strpos(':', $params['host']) !== false)
{
$host = explode(':', $params['host'], 2);
$params['host'] = $host[0];
$params['port'] = $host[1];
}
if( isset($params['host']) )
{
$dns[] = 'host=' . $params['host'];
}
if( isset($params['port']) )
{
$dns[] = 'port=' . $params['port'];
}
if( isset($params['database']) )
{
$dns[] = 'dbname=' . $params['database'];
}
if( isset($params['user']) )
{
$user = $params['user'];
}
if( isset($params['password']) )
{
$password = $params['password'];
}
if( isset($params['prefix']) )
{
$this->prefix = $params['prefix'];
}
// PDO constructor
try
{
parent::__construct('mysql:' . implode(';', $dns), $user, $password);
}
catch(PDOException $error)
{
echo 'Can\'t connect to MySQL database.';
exit;
}
}
/**
* Query-quoted field name.
*
* @param string $name Field name.
* @return string Quoted name.
*/
public function fieldName($name)
{
return '`' . $name . '`';
}
/**
* LIMIT/OFFSET clause for queries.
*
* @param int|bool $limit Limit of rows to be affected by query (false if no limit).
* @param int|bool $offset Number of rows to be skipped before applying query effects (false if no offset).
* @return string LIMIT/OFFSET SQL clause for query.
*/
public function limit($limit = false, $offset = false)
{
// by default this is empty part
$sql = '';
if($limit !== false)
{
$sql = ' LIMIT ';
// OFFSET has no effect if there is no LIMIT
if($offset !== false)
{
$sql .= $offset . ', ';
}
$sql .= $limit;
}
return $sql;
}
}
/**#@-*/
?>

View File

@@ -0,0 +1,110 @@
<?php
/**#@+
* @version 0.0.4
* @since 0.0.4
*/
/**
* @package POT
* @version 0.1.3
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 - 2008 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/
/**
* ODBC connection interface.
*
* <p>
* At all everything that you really need to read from this class documentation is list of parameters for driver's constructor.
* </p>
*
* @package POT
* @version 0.1.3
*/
class OTS_DB_ODBC extends OTS_Base_DB
{
/**
* Creates database connection.
*
* <p>
* Connects to ODBC data source on given arguments.
* </p>
*
* <p>
* List of parameters for this drivers:
* </p>
*
* <ul>
* <li><var>host</var> - database host.</li>
* <li><var>port</var> - ODBC driver.</li>
* <li><var>database</var> - database name.</li>
* <li><var>user</var> - user login.</li>
* <li><var>password</var> - user password.</li>
* <li><var>source</var> - ODBC data source.</li>
* </ul>
*
* <p>
* Note: Since 0.1.3 version <var>source</var> parameter was added.
* </p>
*
* @version 0.1.3
* @param array $params Connection parameters.
* @throws PDOException On PDO operation error.
*/
public function __construct($params)
{
$user = null;
$password = null;
$dns = array();
if( isset($params['host']) )
{
$dns[] = 'HOSTNAME={' . $params['host'] . '}';
}
if( isset($params['port']) )
{
$dns[] = 'DRIVER={' . $params['port'] . '}';
}
if( isset($params['database']) )
{
$dns[] = 'DATABASE={' . $params['database'] . '}';
}
if( isset($params['user']) )
{
$user = $params['user'];
$dns[] = 'UID={' . $user . '}';
}
if( isset($params['password']) )
{
$password = $params['password'];
$dns[] = 'PWD={' . $user . '}';
}
if( isset($params['prefix']) )
{
$this->prefix = $params['prefix'];
}
// composes DNS
$dns = implode(';', $dns);
// source parameter overwrites all other params
if( isset($params['source']) )
{
$dns = $params['source'];
}
// PDO constructor
parent::__construct('odbc:' . $dns, $user, $password);
}
}
/**#@-*/
?>

View File

@@ -0,0 +1,103 @@
<?php
/**#@+
* @version 0.0.4
* @since 0.0.4
*/
/**
* @package POT
* @version 0.1.3
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/
/**
* PostgreSQL connection interface.
*
* <p>
* At all everything that you really need to read from this class documentation is list of parameters for driver's constructor.
* </p>
*
* @package POT
* @version 0.1.3
*/
class OTS_DB_PostgreSQL extends OTS_Base_DB
{
/**
* Creates database connection.
*
* <p>
* Connects to PgSQL (PostgreSQL) database on given arguments.
* </p>
*
* <p>
* List of parameters for this drivers:
* </p>
*
* <ul>
* <li><var>host</var> - database server.</li>
* <li><var>port</var> - port (optional, also it is possible to use host:port in <var>host</var> parameter).</li>
* <li><var>database</var> - database name.</li>
* <li><var>user</var> - user login.</li>
* <li><var>password</var> - user password.</li>
* </ul>
*
* @version 0.0.6
* @param array $params Connection parameters.
* @throws PDOException On PDO operation error.
*/
public function __construct($params)
{
$user = null;
$password = null;
$dns = array();
// host:port support
if( strpos(':', $params['host']) !== false)
{
$host = explode(':', $params['host'], 2);
$params['host'] = $host[0];
$params['port'] = $host[1];
}
if( isset($params['host']) )
{
$dns[] = 'host=' . $params['host'];
}
if( isset($params['port']) )
{
$dns[] = 'port=' . $params['port'];
}
if( isset($params['database']) )
{
$dns[] = 'dbname=' . $params['database'];
}
if( isset($params['user']) )
{
$user = $params['user'];
}
if( isset($params['password']) )
{
$password = $params['password'];
}
if( isset($params['prefix']) )
{
$this->prefix = $params['prefix'];
}
// PDO constructor
parent::__construct('pgsql:' . implode(' ', $dns), $user, $password);
}
}
/**#@-*/
?>

View File

@@ -0,0 +1,361 @@
<?php
/**#@+
* @version 0.0.6
* @since 0.0.6
*/
/**
* Code in this file bases on oryginal OTServ binary format loading C++ code (fileloader.h, fileloader.cpp).
*
* @package POT
* @version 0.1.3
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 - 2008 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/
/**
* Universal OTServ binary formats reader.
*
* <p>
* This class is general class that handle node-based binary OTServ files. It provides no file format-related logic, only loading nodes from files. To open given file format you need to use proper class like {@link OTS_OTBMFile OTS_OTBMFile} or {@link OTS_ItemsList OTS_ItemsList} classes.
* </p>
*
* <p>
* This class is mostly usefull when you create own extensions for POT code.
* </p>
*
* @package POT
* @version 0.1.3
* @property-write IOTS_FileCache $cacheDriver Cache driver.
*/
class OTS_FileLoader
{
/**
* Start of node.
*/
const NODE_START = 0xFE;
/**
* End of node.
*/
const NODE_END = 0xFF;
/**
* Escape another special byte.
*/
const ESCAPE_CHAR = 0xFD;
/**
* File handle.
*
* @var resource
*/
private $file;
/**
* Root node.
*
* @var OTS_FileNode
*/
protected $root;
/**
* Cache handler.
*
* @var IOTS_FileCache
*/
protected $cache;
/**
* Magic PHP5 method.
*
* <p>
* Allows object serialisation.
* </p>
*
* @version 0.0.6
* @since 0.0.6
* @return array List of properties that should be saved.
*/
public function __sleep()
{
return array('root', 'cache');
}
/**
* Creates clone of object.
*
* <p>
* Copy of object needs to have different ID.
* </p>
*
* @version 0.0.6
* @since 0.0.6
*/
public function __clone()
{
// clones node tree
$this->root = clone $this->root;
}
/**
* Magic PHP5 method.
*
* <p>
* Allows object importing from {@link http://www.php.net/manual/en/function.var-export.php var_export()}.
* </p>
*
* @version 0.0.6
* @since 0.0.6
* @param array $properties List of object properties.
*/
public static function __set_state($properties)
{
$object = new self();
// loads properties
foreach($properties as $name => $value)
{
$object->$name = $value;
}
return $object;
}
/**
* Sets cache handler.
*
* <p>
* You have to set cache driver before loading/saving any file in order to apply it to that file.
* </p>
*
* @param IOTS_FileCache $cache Cache handler (leave this parameter if you want to unset caching).
*/
public function setCacheDriver(IOTS_FileCache $cache = null)
{
$this->cache = $cache;
}
/**
* Opens file.
*
* @version 0.1.3
* @param string $file Filepath.
* @throws E_OTS_FileLoaderError When error occurs during file operation.
*/
public function loadFile($file)
{
// attemts to read from cache
if( isset($this->cache) )
{
$this->root = $this->cache->readCache( md5_file($file) );
// checks if cache was loaded
if( isset($this->root) )
{
return;
}
}
// opens for read in binary mode
$this->file = fopen($file, 'rb');
if($this->file)
{
// reads file version
$version = unpack('V', fread($this->file, 4) );
if($version[1] > 0)
{
throw new E_OTS_FileLoaderError(E_OTS_FileLoaderError::ERROR_INVALID_FILE_VERSION);
}
$this->safeSeek(4);
if( $this->readByte() != self::NODE_START)
{
throw new E_OTS_FileLoaderError(E_OTS_FileLoaderError::ERROR_INVALID_FORMAT);
}
// reads root node
$this->root = new OTS_FileNode();
$this->parseNode($this->root);
fclose($this->file);
// writes new cache
if( isset($this->cache) )
{
$this->cache->writeCache( md5_file($file), $this->root);
}
}
// failed to open the file
else
{
throw new E_OTS_FileLoaderError(E_OTS_FileLoaderError::ERROR_CAN_NOT_OPEN);
}
}
/**
* Loades node from file.
*
* @param OTS_FileNode $node Node into which file fragment should be parsed.
* @throws E_OTS_FileLoaderError When error occurs during file operation.
*/
private function parseNode(OTS_FileNode $node)
{
$current = $node;
// reads node type
$current->setType( $this->readByte() );
$buffer = '';
$propertiesSet = false;
while(true)
{
// reads single byte from file
$byte = $this->readByte();
switch($byte)
{
// start of new node
case self::NODE_START:
// reads child node
$child = new OTS_FileNode();
$current->setBuffer($buffer);
$propertiesSet = true;
$current->setChild($child);
$this->parseNode($child);
break;
// end of current node
case self::NODE_END:
if(!$propertiesSet)
{
$current->setBuffer($buffer);
}
// end of file
if($node === $this->root)
{
return;
}
switch( $this->readByte() )
{
// starts next node
case self::NODE_START:
$next = new OTS_FileNode();
$current->setNext($next);
$current = $next;
$current->setType( $this->readByte() );
$propertiesSet = false;
$buffer = '';
break;
// up 1 level and move 1 position back
case self::NODE_END:
$this->safeSeek( $this->safeTell() - 1);
return;
// invliad file format
default:
throw new E_OTS_FileLoaderError(E_OTS_FileLoaderError::ERROR_INVALID_FORMAT);
}
break;
// ignores next character
case self::ESCAPE_CHAR:
$buffer .= chr( $this->readByte() );
break;
// normal character
default:
$buffer .= chr($byte);
}
}
}
/**
* Reads single byte from file.
*
* @return int Read value.
* @throws E_OTS_FileLoaderError When error occurs during file operation.
*/
private function readByte()
{
$value = fgetc($this->file);
// checks eof
if($value === false)
{
throw new E_OTS_FileLoaderError(E_OTS_FileLoaderError::ERROR_EOF);
}
return ord($value);
}
/**
* Seeks file pointer into given position.
*
* @param int $pos Seek position.
* @throws E_OTS_FileLoaderError When error occurs during file operation.
*/
private function safeSeek($pos)
{
if( fseek($this->file, $pos, SEEK_SET) == -1)
{
// error occured
throw new E_OTS_FileLoaderError(E_OTS_FileLoaderError::ERROR_SEEK_ERROR);
}
}
/**
* Returns current position in file.
*
* @return int Position in file.
* @throws E_OTS_FileLoaderError When error occurs during file operation.
*/
private function safeTell()
{
// reads file position
$pos = ftell($this->file);
// checks if operation succeeded
if($pos === false)
{
throw new E_OTS_FileLoaderError(E_OTS_FileLoaderError::ERROR_TELL_ERROR);
}
return $pos;
}
/**
* Magic PHP5 method.
*
* @version 0.1.0
* @since 0.1.0
* @param string $name Property name.
* @param mixed $value Property value.
* @throws OutOfBoundsException For non-supported properties.
*/
public function __set($name, $value)
{
switch($name)
{
case 'cacheDriver':
$this->setCacheDriver($value);
break;
// not-supported
default:
throw new OutOfBoundsException();
}
}
}
/**#@-*/
?>

View File

@@ -0,0 +1,186 @@
<?php
/**#@+
* @version 0.0.6
* @since 0.0.6
*/
/**
* Code in this file bases on oryginal OTServ binary format loading C++ code (fileloader.h, fileloader.cpp).
*
* @package POT
* @version 0.1.2
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 - 2008 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/
/**
* OTServ binary file node representation.
*
* <p>
* This file extends {@link OTS_Buffer OTS_Buffer class} for nodes tree logic with siblings and childs.
* </p>
*
* @package POT
* @version 0.1.2
* @property OTS_FileNode $next Next sibling node.
* @property OTS_FileNode $child First child node.
* @property int $type Node type.
*/
class OTS_FileNode extends OTS_Buffer
{
/**
* Next sibling node.
*
* @var OTS_FileNode
*/
private $next;
/**
* First child node.
*
* @var OTS_FileNode
*/
private $child;
/**
* Node type.
*
* @var int
*/
private $type;
/**
* Creates clone of object.
*
* <p>
* Creates complete tree copy by copying sibling and child nodes.
* </p>
*/
public function __clone()
{
// clones conencted nodes
if( isset($this->child) )
{
$this->child = clone $this->child;
}
if( isset($this->next) )
{
$this->next = clone $this->next;
}
}
/**
* Returs next sibling.
*
* @return OTS_FileNode Sibling node.
*/
public function getNext()
{
return $this->next;
}
/**
* Sets next sibling.
*
* @param OTS_FileNode Sibling node.
*/
public function setNext(OTS_FileNode $next)
{
$this->next = $next;
}
/**
* Returs first child.
*
* @return OTS_FileNode Child node.
*/
public function getChild()
{
return $this->child;
}
/**
* Sets first child.
*
* @param OTS_FileNode Child node.
*/
public function setChild(OTS_FileNode $child)
{
$this->child = $child;
}
/**
* Returs node type.
*
* @return int Node type.
*/
public function getType()
{
return $this->type;
}
/**
* Sets node type.
*
* @param int Node type.
*/
public function setType($type)
{
$this->type = $type;
}
/**
* Magic PHP5 method.
*
* @version 0.1.2
* @since 0.1.0
* @param string $name Property name.
* @return mixed Property value.
* @throws OutOfBoundsException For non-supported properties.
* @throws E_OTS_OutOfBuffer When there is read attemp after end of stream.
*/
public function __get($name)
{
switch($name)
{
// simple properties
case 'next':
case 'child':
case 'type':
return $this->$name;
default:
return parent::__get($name);
}
}
/**
* Magic PHP5 method.
*
* @version 0.1.2
* @since 0.1.0
* @param string $name Property name.
* @param mixed $value Property value.
* @throws OutOfBoundsException For non-supported properties.
*/
public function __set($name, $value)
{
switch($name)
{
// simple properties
case 'next':
case 'child':
case 'type':
$this->$name = $value;
break;
default:
parent::__set($name, $value);
}
}
}
/**#@-*/
?>

View File

@@ -0,0 +1,670 @@
<?php
/**#@+
* @version 0.0.1
*/
/**
* @package POT
* @version 0.1.4
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 - 2008 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/
/**
* OTServ user group abstraction.
*
* @package POT
* @version 0.1.4
* @property string $name Group name.
* @property int $flags Access flags.
* @property int $access Access level.
* @property int $maxDepotItems Maximum count of items in depot.
* @property int $maxVIPList Maximum count of entries in VIP list.
* @property-read bool $loaded Loaded state check.
* @property-read int $id Row ID.
* @property-read OTS_Players_List $playersList List of members of this group.
*/
class OTS_Group extends OTS_Row_DAO implements IteratorAggregate, Countable
{
/**
* Group data.
*
* @var array
*/
protected $data = array('flags' => 0, 'customFlags' => 0, 'access' => 0, 'ghostAccess' => 0);
/**
* Spell info resource.
*
* @var DOMElement
*/
private $element;
/**
* Sets group info.
*
* @param DOMElement $group Group info.
*/
public function __construct($data)
{
$this->data = $data;
}
/**
* Checks if object is loaded.
*
* @version 0.0.1
* @return bool Load state.
*/
public function isLoaded()
{
return isset($this->data['id']);
}
/**
* Loads group with given id.
*
* @version 0.0.5
* @param int $id Group number.
* @throws PDOException On PDO operation error.
*/
public function load($element)
{
// SELECT query on database
// $this->data = $this->db->query('SELECT ' . $this->db->fieldName('id') . ', ' . $this->db->fieldName('name') . ', ' . $this->db->fieldName('flags') . ', ' . $this->db->fieldName('access') . ', ' . $this->db->fieldName('maxdepotitems') . ', ' . $this->db->fieldName('maxviplist') . ' FROM ' . $this->db->tableName('groups') . ' WHERE ' . $this->db->fieldName('id') . ' = ' . (int) $id)->fetch();
$this->element = $element;
// $groups = new DOMDocument();
// $groups->load($path);
// foreach($groups->getElementsByTagName('group') as $group)
// {
// if($group->getAttribute('id') == $_id)
// {
$this->data['id'] = $element->getAttribute('id');
$this->data['access'] = $element->getAttribute('access');
$this->data['name'] = $element->getAttribute('name');
$this->data['maxviplist'] = $element->getAttribute('maxVips');
$this->data['maxdepotitems'] = $element->getAttribute('depotLimit');
// }
// }
}
/**
* Loads group by it's name.
*
* @version 0.1.1
* @since 0.1.1
* @param string $name Group name.
* @throws PDOException On PDO operation error.
*/
public function find($name)
{
// finds group's ID
$id = $this->db->query('SELECT ' . $this->db->fieldName('id') . ' FROM ' . $this->db->tableName('groups') . ' WHERE ' . $this->db->fieldName('name') . ' = ' . $this->db->quote($name) )->fetch();
// if anything was found
if( isset($id['id']) )
{
$this->load($id['id']);
}
}
/**
* Saves group in database.
*
* <p>
* If group is not loaded to represent any existing group it will create new row for it.
* </p>
*
* @version 0.0.5
* @throws PDOException On PDO operation error.
*/
public function save()
{
// updates existing group
if( isset($this->data['id']) )
{
// UPDATE query on database
$this->db->query('UPDATE ' . $this->db->tableName('groups') . ' SET ' . $this->db->fieldName('name') . ' = ' . $this->db->quote($this->data['name']) . ', ' . $this->db->fieldName('flags') . ' = ' . $this->data['flags'] . ', ' . $this->db->fieldName('access') . ' = ' . $this->data['access'] . ', ' . $this->db->fieldName('maxdepotitems') . ' = ' . $this->data['maxdepotitems'] . ', ' . $this->db->fieldName('maxviplist') . ' = ' . $this->data['maxviplist'] . ' WHERE ' . $this->db->fieldName('id') . ' = ' . $this->data['id']);
}
// creates new group
else
{
// INSERT query on database
$this->db->query('INSERT INTO ' . $this->db->tableName('groups') . ' (' . $this->db->fieldName('name') . ', ' . $this->db->fieldName('flags') . ', ' . $this->db->fieldName('access') . ', ' . $this->db->fieldName('maxdepotitems') . ', ' . $this->db->fieldName('maxviplist') . ') VALUES (' . $this->db->quote($this->data['name']) . ', ' . $this->data['flags'] . ', ' . $this->data['access'] . ', ' . $this->data['maxdepotitems'] . ', ' . $this->data['maxviplist'] . ')');
// ID of new group
$this->data['id'] = $this->db->lastInsertId();
}
}
/**
* Group ID.
*
* <p>
* Note: Since 0.0.3 version this method throws {@link E_OTS_NotLoaded E_OTS_NotLoaded exception} instead of triggering E_USER_WARNING.
* </p>
*
* @version 0.0.3
* @return int Group ID.
* @throws E_OTS_NotLoaded If group is not loaded.
*/
public function getId()
{
if( !isset($this->data['id']) )
{
throw new E_OTS_NotLoaded();
}
return $this->data['id'];
}
/**
* Group name.
*
* <p>
* Note: Since 0.0.3 version this method throws {@link E_OTS_NotLoaded E_OTS_NotLoaded exception} instead of triggering E_USER_WARNING.
* </p>
*
* @version 0.0.3
* @return string Name.
* @throws E_OTS_NotLoaded If group is not loaded.
*/
public function getName()
{
if( !isset($this->data['name']) )
{
throw new E_OTS_NotLoaded();
}
return $this->data['name'];
}
/**
* Sets group's name.
*
* <p>
* This method only updates object state. To save changes in database you need to use {@link OTS_Group::save() save() method} to flush changed to database.
* </p>
*
* @param string $name Name.
*/
public function setName($name)
{
$this->data['name'] = (string) $name;
}
/**
* Rights flags.
*
* <p>
* Note: Since 0.0.3 version this method throws {@link E_OTS_NotLoaded E_OTS_NotLoaded exception} instead of triggering E_USER_WARNING.
* </p>
*
* @version 0.0.3
* @return int Flags.
* @throws E_OTS_NotLoaded If group is not loaded.
*/
public function getFlags()
{
if( !isset($this->data['flags']) )
{
throw new E_OTS_NotLoaded();
}
return $this->data['flags'];
}
/**
* Sets rights flags.
*
* <p>
* This method only updates object state. To save changes in database you need to use {@link OTS_Group::save() save() method} to flush changed to database.
* </p>
*
* @param int $flags Flags.
*/
public function setFlags($flags)
{
$this->data['flags'] = (int) $flags;
}
/**
* Custom flags.
*
* <p>
* Note: Since 0.0.3 version this method throws {@link E_OTS_NotLoaded E_OTS_NotLoaded exception} instead of triggering E_USER_WARNING.
* </p>
*
* @version 0.0.3
* @return int Flags.
* @throws E_OTS_NotLoaded If group is not loaded.
*/
public function getCustomFlags()
{
if( !isset($this->data['customFlags']) )
{
throw new E_OTS_NotLoaded();
}
return $this->data['customFlags'];
}
/**
* Sets rights flags.
*
* <p>
* This method only updates object state. To save changes in database you need to use {@link OTS_Group::save() save() method} to flush changed to database.
* </p>
*
* @param int $flags Flags.
*/
public function setCustomFlags($flags)
{
$this->data['customFlags'] = (int) $flags;
}
/**
* Access level.
*
* <p>
* Note: Since 0.0.3 version this method throws {@link E_OTS_NotLoaded E_OTS_NotLoaded exception} instead of triggering E_USER_WARNING.
* </p>
*
* @version 0.0.3
* @return int Access level.
* @throws E_OTS_NotLoaded If group is not loaded.
*/
public function getAccess()
{
if( !isset($this->data['access']) )
{
throw new E_OTS_NotLoaded();
}
return $this->data['access'];
}
/**
* Sets access level.
*
* <p>
* This method only updates object state. To save changes in database you need to use {@link OTS_Group::save() save() method} to flush changed to database.
* </p>
*
* @param int $access Access level.
*/
public function setAccess($access)
{
$this->data['access'] = (int) $access;
}
/**
* Maximum count of items in depot.
*
* <p>
* Note: Since 0.0.3 version this method throws {@link E_OTS_NotLoaded E_OTS_NotLoaded exception} instead of triggering E_USER_WARNING.
* </p>
*
* @version 0.0.3
* @return int Maximum value.
* @throws E_OTS_NotLoaded If group is not loaded.
*/
public function getMaxDepotItems()
{
if( !isset($this->data['maxdepotitems']) )
{
throw new E_OTS_NotLoaded();
}
return $this->data['maxdepotitems'];
}
/**
* Sets maximum count of items in depot.
*
* <p>
* This method only updates object state. To save changes in database you need to use {@link OTS_Group::save() save() method} to flush changed to database.
* </p>
*
* @param int $maxdepotitems Maximum value.
*/
public function setMaxDepotItems($maxdepotitems)
{
$this->data['maxdepotitems'] = (int) $maxdepotitems;
}
/**
* Maximum count of players in VIP list.
*
* <p>
* Note: Since 0.0.3 version this method throws {@link E_OTS_NotLoaded E_OTS_NotLoaded exception} instead of triggering E_USER_WARNING.
* </p>
*
* @version 0.0.3
* @return int Maximum value.
* @throws E_OTS_NotLoaded If group is not loaded.
*/
public function getMaxVIPList()
{
if( !isset($this->data['maxviplist']) )
{
throw new E_OTS_NotLoaded();
}
return $this->data['maxviplist'];
}
/**
* Sets maximum count of players in VIP list.
*
* <p>
* This method only updates object state. To save changes in database you need to use {@link OTS_Group::save() save() method} to flush changed to database.
* </p>
*
* @param int $maxviplist Maximum value.
*/
public function setMaxVIPList($maxviplist)
{
$this->data['maxviplist'] = (int) $maxviplist;
}
/**
* Reads custom field.
*
* <p>
* Reads field by it's name. Can read any field of given record that exists in database.
* </p>
*
* <p>
* Note: You should use this method only for fields that are not provided in standard setters/getters (SVN fields). This method runs SQL query each time you call it so it highly overloads used resources.
* </p>
*
* @version 0.0.5
* @since 0.0.3
* @param string $field Field name.
* @return string Field value.
* @throws E_OTS_NotLoaded If group is not loaded.
* @throws PDOException On PDO operation error.
*/
public function getCustomField($field)
{
if( !isset($this->data['id']) )
{
throw new E_OTS_NotLoaded();
}
$value = $this->db->query('SELECT ' . $this->db->fieldName($field) . ' FROM ' . $this->db->tableName('groups') . ' WHERE ' . $this->db->fieldName('id') . ' = ' . $this->data['id'])->fetch();
return $value[$field];
}
/**
* Writes custom field.
*
* <p>
* Write field by it's name. Can write any field of given record that exists in database.
* </p>
*
* <p>
* Note: You should use this method only for fields that are not provided in standard setters/getters (SVN fields). This method runs SQL query each time you call it so it highly overloads used resources.
* </p>
*
* <p>
* Note: Make sure that you pass $value argument of correct type. This method determinates whether to quote field name. It is safe - it makes you sure that no unproper queries that could lead to SQL injection will be executed, but it can make your code working wrong way. For example: $object->setCustomField('foo', '1'); will quote 1 as as string ('1') instead of passing it as a integer.
* </p>
*
* @version 0.0.5
* @since 0.0.3
* @param string $field Field name.
* @param mixed $value Field value.
* @throws E_OTS_NotLoaded If group is not loaded.
* @throws PDOException On PDO operation error.
*/
public function setCustomField($field, $value)
{
if( !isset($this->data['id']) )
{
throw new E_OTS_NotLoaded();
}
// quotes value for SQL query
if(!( is_int($value) || is_float($value) ))
{
$value = $this->db->quote($value);
}
$this->db->query('UPDATE ' . $this->db->tableName('groups') . ' SET ' . $this->db->fieldName($field) . ' = ' . $value . ' WHERE ' . $this->db->fieldName('id') . ' = ' . $this->data['id']);
}
/**
* @version 0.1.0
* @return array Array of OTS_Player objects from given group.
* @throws E_OTS_NotLoaded If group is not loaded.
* @deprecated 0.0.5 Use getPlayersList().
*/
public function getPlayers()
{
if( !isset($this->data['id']) )
{
throw new E_OTS_NotLoaded();
}
$players = array();
foreach( $this->db->query('SELECT ' . $this->db->fieldName('id') . ' FROM ' . $this->db->tableName('players') . ' WHERE ' . $this->db->fieldName('group_id') . ' = ' . $this->data['id'])->fetchAll() as $player)
{
// creates new object
$object = new OTS_Player();
$object->load($player['id']);
$players[] = $object;
}
return $players;
}
/**
* List of characters in group.
*
* <p>
* In difference to {@link OTS_Group::getPlayers() getPlayers() method} this method returns filtered {@link OTS_Players_List OTS_Players_List} object instead of array of {@link OTS_Player OTS_Player} objects. It is more effective since OTS_Player_List doesn't perform all rows loading at once.
* </p>
*
* <p>
* Note: Returned object is only prepared, but not initialised. When using as parameter in foreach loop it doesn't matter since it will return it's iterator, but if you will wan't to execute direct operation on that object you will need to call {@link OTS_Base_List::rewind() rewind() method} first.
* </p>
*
* @version 0.1.4
* @since 0.0.5
* @return OTS_Players_List List of players from current group.
* @throws E_OTS_NotLoaded If group is not loaded.
*/
public function getPlayersList()
{
if( !isset($this->data['id']) )
{
throw new E_OTS_NotLoaded();
}
// creates filter
$filter = new OTS_SQLFilter();
$filter->compareField('group_id', (int) $this->data['id']);
$filter->compareField('deleted', 0);
// creates list object
$list = new OTS_Players_List();
$list->setFilter($filter);
return $list;
}
/**
* Deletes group.
*
* @version 0.0.5
* @since 0.0.5
* @throws E_OTS_NotLoaded If group is not loaded.
* @throws PDOException On PDO operation error.
*/
public function delete()
{
if( !isset($this->data['id']) )
{
throw new E_OTS_NotLoaded();
}
// deletes row from database
$this->db->query('DELETE FROM ' . $this->db->tableName('groups') . ' WHERE ' . $this->db->fieldName('id') . ' = ' . $this->data['id']);
// resets object handle
unset($this->data['id']);
}
/**
* Returns players iterator.
*
* <p>
* There is no need to implement entire Iterator interface since we have {@link OTS_Players_List players list class} for it.
* </p>
*
* @version 0.0.5
* @since 0.0.5
* @throws E_OTS_NotLoaded If group is not loaded.
* @throws PDOException On PDO operation error.
* @return Iterator List of players.
*/
public function getIterator()
{
return $this->getPlayersList();
}
/**
* Returns number of player within.
*
* @version 0.0.5
* @since 0.0.5
* @throws E_OTS_NotLoaded If group is not loaded.
* @throws PDOException On PDO operation error.
* @return int Count of players.
*/
public function count()
{
return $this->getPlayersList()->count();
}
/**
* Magic PHP5 method.
*
* @version 0.1.0
* @since 0.1.0
* @param string $name Property name.
* @return mixed Property value.
* @throws E_OTS_NotLoaded If group is not loaded.
* @throws OutOfBoundsException For non-supported properties.
* @throws PDOException On PDO operation error.
*/
public function __get($name)
{
switch($name)
{
case 'loaded':
return $this->isLoaded();
case 'id':
return $this->getId();
case 'name':
return $this->getName();
case 'flags':
return $this->getFlags();
case 'access':
return $this->getAccess();
case 'maxDepotItems':
return $this->getMaxDepotItems();
case 'maxVIPList':
return $this->getMaxVIPList();
case 'playersList':
return $this->getPlayersList();
default:
throw new OutOfBoundsException();
}
}
/**
* Magic PHP5 method.
*
* @version 0.1.0
* @since 0.1.0
* @param string $name Property name.
* @param mixed $value Property value.
* @throws OutOfBoundsException For non-supported properties.
* @throws PDOException On PDO operation error.
*/
public function __set($name, $value)
{
switch($name)
{
case 'id':
$this->data['id'] = $value;
break;
case 'name':
$this->setName($value);
break;
case 'flags':
$this->setFlags($value);
break;
case 'access':
$this->setAccess($value);
break;
case 'maxDepotItems':
$this->setMaxDepotItems($value);
break;
case 'maxVIPList':
$this->setMaxVIPList($value);
break;
default:
throw new OutOfBoundsException();
}
}
/**
* Returns string representation of object.
*
* <p>
* If any display driver is currently loaded then it uses it's method. Else it returns group name.
* </p>
*
* @version 0.1.3
* @since 0.1.0
* @return string String representation of object.
*/
public function __toString()
{
$ots = POT::getInstance();
// checks if display driver is loaded
if( $ots->isDisplayDriverLoaded() )
{
return $ots->getDisplayDriver()->displayGroup($this);
}
return $this->getName();
}
}
/**#@-*/
?>

View File

@@ -0,0 +1,192 @@
<?php
/**
* @package POT
* @version 0.1.3
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 - 2008 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/
/**
* List of groups.
*
* @package POT
* @version 0.1.3
*/
class OTS_Groups_List implements IteratorAggregate, Countable
{
/**
* Groups.
*
* @var array
*/
private $groups = array();
/**
* Loads group list.
*
* @param string $file Groups file name.
* @throws DOMException On DOM operation error.
*/
public function __construct($file = '')
{
global $cache;
if(tableExist('groups')) { // read groups from database
foreach($db->query('SELECT `id`, `name`, `access` FROM `groups`;') as $group)
{
$info = array();
$info['id'] = $group['id'];
$info['name'] = $group['name'];
$info['access'] = $group['name'];
$this->groups[$group['id']] = new OTS_Group($info);
}
return;
}
if(!isset($file[0]))
{
global $config;
$file = $config['data_path'] . 'XML/groups.xml';
}
$data = array();
if($cache->enabled())
{
$tmp = '';
if($cache->fetch('groups', $tmp))
$data = unserialize($tmp);
else
{
$groups = new DOMDocument();
$groups->load($file);
// loads groups
foreach( $groups->getElementsByTagName('group') as $group)
{
$data[$group->getAttribute('id')] = array(
'id' => $group->getAttribute('id'),
'name' => $group->getAttribute('name'),
'access' => $group->getAttribute('access')
);
}
$cache->set('groups', serialize($data), 120);
}
foreach($data as $id => $info)
$this->groups[ $id ] = new OTS_Group($info);
}
else
{
// loads DOM document
$groups = new DOMDocument();
$groups->load($file);
// loads groups
foreach($groups->getElementsByTagName('group') as $group)
{
$data[$group->getAttribute('id')] = array(
'id' => $group->getAttribute('id'),
'name' => $group->getAttribute('name'),
'access' => $group->getAttribute('access')
);
$this->groups[ $group->getAttribute('id') ] = new OTS_Group($data[$group->getAttribute('id')]);
//echo $this->getGroup(1)->getName();
}
}
}
/**
* Returns given group.
*
* @version 0.1.3
* @param int $id Group id.
* @return OTS_Group group wrapper.
* @throws OutOfBoundsException If group does not exist.
*/
public function getGroup($id)
{
if( isset($this->groups[$id]) )
{
return $this->groups[$id];
}
return false;
}
/**
* Returns all groups.
*
* @version 0.1.3
* @return array with OTS_Group group wrappers.
* @throws OutOfBoundsException If group does not exist.
*/
public function getGroups()
{
if( isset($this->groups) )
{
return $this->groups;
}
throw new OutOfBoundsException();
}
/**
* Returns string representation of object.
*
* <p>
* If any display driver is currently loaded then it uses it's method.
* </p>
*
* @version 0.1.3
* @since 0.1.0
* @return string String representation of object.
*/
public function __toString()
{
$ots = POT::getInstance();
// checks if display driver is loaded
if( $ots->isDisplayDriverLoaded() )
{
return $ots->getDisplayDriver()->displayGroupsList($this);
}
return (string) $this->count();
}
/**
* Iterator for all groups.
*
* <p>
* Returned object will continousely iterate through all kind of groups.
* </p>
*
* @version 0.1.5
* @since 0.1.5
* @return AppendIterator Iterator for all groups.
*/
public function getIterator()
{
$iterator = new AppendIterator();
$iterator->append( new ArrayIterator($this->groups) );
return $iterator;
}
/**
* Number of all loaded groups.
*
* @version 0.1.5
* @since 0.1.5
* @return int Amount of all groups.
*/
public function count()
{
return count($this->groups);
}
}
?>

View File

@@ -0,0 +1,819 @@
<?php
/**#@+
* @version 0.0.4
* @since 0.0.4
*/
/**
* @package POT
* @version 0.1.4
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 - 2008 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/
/**
* OTServ guild abstraction.
*
* @package POT
* @version 0.1.4
* @property string $read Guild name.
* @property OTS_Player $owner Guild founder.
* @property int $creationData Guild creation data (mostly timestamp).
* @property-read int $id Guild ID.
* @property-read bool $loaded Loaded state.
* @property-read OTS_GuildRanks_List $guildRanksList Ranks in this guild.
* @property-read array $invites List of invited players.
* @property-read array $requests List of players that requested invites.
* @property-write IOTS_GuildAction $invitesDriver Invitations handler.
* @property-write IOTS_GuildAction $requestsDriver Membership requests handler.
* @tutorial POT/Guilds.pkg
*/
class OTS_Guild extends OTS_Row_DAO implements IteratorAggregate, Countable
{
/**
* Guild data.
*
* @var array
*/
private $data = array();
/**
* Invites handler.
*
* @var IOTS_GuildAction
*/
private $invites;
/**
* Membership requests handler.
*
* @var IOTS_GuildAction
*/
private $requests;
/**
* Magic PHP5 method.
*
* Allows object serialisation.
*
* @return array List of properties that should be saved.
*/
public function __sleep()
{
return array('data', 'invites', 'requests');
}
/**
* Creates clone of object.
*
* <p>
* Copy of object needs to have different ID. Also invites and requests drivers are copied and assigned to object's copy.
* </p>
*
* @version 0.1.3
*/
public function __clone()
{
unset($this->data['id']);
if( isset($this->invites) )
{
$this->invites = clone $this->invites;
$this->invites->__construct($this);
}
if( isset($this->requests) )
{
$this->requests = clone $this->requests;
$this->requests->__construct($this);
}
}
/**
* Assigns invites handler.
*
* @param IOTS_GuildAction $invites Invites driver (don't pass it to clear driver).
*/
public function setInvitesDriver(IOTS_GuildAction $invites = null)
{
$this->invites = $invites;
}
/**
* Assigns requests handler.
*
* @param IOTS_GuildAction $requests Membership requests driver (don't pass it to clear driver).
*/
public function setRequestsDriver(IOTS_GuildAction $requests = null)
{
$this->requests = $requests;
}
/**
* Loads guild with given id.
*
* @version 0.0.5
* @param int $id Guild's ID.
* @throws PDOException On PDO operation error.
*/
public function load($id)
{
$ownerid = 'ownerid';
if(fieldExist('owner_id', 'guilds'))
$ownerid = 'owner_id';
$creationdata = 'creationdata';
if(fieldExist('creationdate', 'guilds'))
$creationdata = 'creationdate';
else if(fieldExist('creation_time', 'guilds'))
$creationdata = 'creation_time';
// SELECT query on database
$this->data = $this->db->query('SELECT `id`, `name`, `' . $ownerid . '` as `ownerid`, `' . $creationdata . '` as `creationdata` FROM `guilds` WHERE `id` = ' . (int) $id)->fetch();
}
/**
* Loads guild by it's name.
*
* @version 0.0.5
* @param string $name Guild's name.
* @throws PDOException On PDO operation error.
*/
public function find($name)
{
// finds player's ID
$id = $this->db->query('SELECT ' . $this->db->fieldName('id') . ' FROM ' . $this->db->tableName('guilds') . ' WHERE ' . $this->db->fieldName('name') . ' = ' . $this->db->quote($name) )->fetch();
// if anything was found
if( isset($id['id']) )
{
$this->load($id['id']);
}
}
/**
* Checks if object is loaded.
*
* @return bool Load state.
*/
public function isLoaded()
{
return isset($this->data['id']);
}
/**
* Saves guild in database.
*
* <p>
* If guild is not loaded to represent any existing group it will create new row for it.
* </p>
*
* @version 0.0.5
* @throws PDOException On PDO operation error.
*/
public function save()
{
$ownerid = 'ownerid';
if(fieldExist('owner_id', 'guilds'))
$ownerid = 'owner_id';
$creationdata = 'creationdata';
if(fieldExist('creationdate', 'guilds'))
$creationdata = 'creationdate';
else if(fieldExist('creation_time', 'guilds'))
$creationdata = 'creation_time';
// updates existing guild
if( isset($this->data['id']) )
{
// UPDATE query on database
$this->db->query('UPDATE `guilds` SET `name` = ' . $this->db->quote($this->data['name']) . ', `' . $ownerid . '` = ' . $this->data['ownerid'] . ', `' . $creationdata . '` = ' . $this->data['creationdata'] . ' WHERE `id` = ' . $this->data['id']);
}
// creates new guild
else
{
// INSERT query on database
$this->db->query('INSERT INTO `guilds` (`name`, `' . $ownerid . '`, `' . $creationdata . '`) VALUES (' . $this->db->quote($this->data['name']) . ', ' . $this->data['ownerid'] . ', ' . $this->data['creationdata'] . ')');
// ID of new group
$this->data['id'] = $this->db->lastInsertId();
}
}
/**
* Guild ID.
*
* @return int Guild ID.
* @throws E_OTS_NotLoaded If guild is not loaded.
*/
public function getId()
{
if( !isset($this->data['id']) )
{
throw new E_OTS_NotLoaded();
}
return $this->data['id'];
}
/**
* Guild name.
*
* @return string Guild's name.
* @throws E_OTS_NotLoaded If guild is not loaded.
*/
public function getName()
{
if( !isset($this->data['name']) )
{
throw new E_OTS_NotLoaded();
}
return $this->data['name'];
}
/**
* Sets guild's name.
*
* <p>
* This method only updates object state. To save changes in database you need to use {@link OTS_Guild::save() save() method} to flush changed to database.
* </p>
*
* @param string $name Name.
*/
public function setName($name)
{
$this->data['name'] = (string) $name;
}
/**
* Returns owning player of this player.
*
* @version 0.1.0
* @return OTS_Player Owning player.
* @throws E_OTS_NotLoaded If guild is not loaded.
* @throws PDOException On PDO operation error.
*/
public function getOwner()
{
if( !isset($this->data['ownerid']) )
{
throw new E_OTS_NotLoaded();
}
$owner = new OTS_Player();
$owner->load($this->data['ownerid']);
return $owner;
}
/**
* Assigns guild to owner.
*
* <p>
* This method only updates object state. To save changes in database you need to use {@link OTS_Guild::save() save() method} to flush changed to database.
* </p>
*
* @param OTS_Player $owner Owning player.
* @throws E_OTS_NotLoaded If given <var>$owner</var> object is not loaded.
*/
public function setOwner(OTS_Player $owner)
{
$this->data['ownerid'] = $owner->getId();
}
/**
* Guild creation data.
*
* @return int Guild creation data.
* @throws E_OTS_NotLoaded If guild is not loaded.
*/
public function getCreationData()
{
if( !isset($this->data['creationdata']) )
{
throw new E_OTS_NotLoaded();
}
return $this->data['creationdata'];
}
/**
* Sets guild creation data.
*
* <p>
* This method only updates object state. To save changes in database you need to use {@link OTS_Guild::save() save() method} to flush changed to database.
* </p>
*
* @param int $creationdata Guild creation data.
*/
public function setCreationData($creationdata)
{
$this->data['creationdata'] = (int) $creationdata;
}
/**
* Reads custom field.
*
* <p>
* Reads field by it's name. Can read any field of given record that exists in database.
* </p>
*
* <p>
* Note: You should use this method only for fields that are not provided in standard setters/getters (SVN fields). This method runs SQL query each time you call it so it highly overloads used resources.
* </p>
*
* @version 0.0.8
* @param string $field Field name.
* @return string Field value.
* @throws E_OTS_NotLoaded If guild is not loaded.
* @throws PDOException On PDO operation error.
*/
public function getCustomField($field)
{
if( !isset($this->data['id']) )
{
throw new E_OTS_NotLoaded();
}
$value = $this->db->query('SELECT ' . $this->db->fieldName($field) . ' FROM ' . $this->db->tableName('guilds') . ' WHERE ' . $this->db->fieldName('id') . ' = ' . $this->data['id'])->fetch();
return $value[$field];
}
/**
* Writes custom field.
*
* <p>
* Write field by it's name. Can write any field of given record that exists in database.
* </p>
*
* <p>
* Note: You should use this method only for fields that are not provided in standard setters/getters (SVN fields). This method runs SQL query each time you call it so it highly overloads used resources.
* </p>
*
* <p>
* Note: Make sure that you pass $value argument of correct type. This method determinates whether to quote field value. It is safe - it makes you sure that no unproper queries that could lead to SQL injection will be executed, but it can make your code working wrong way. For example: $object->setCustomField('foo', '1'); will quote 1 as as string ('1') instead of passing it as a integer.
* </p>
*
* @version 0.0.5
* @param string $field Field name.
* @param mixed $value Field value.
* @throws E_OTS_NotLoaded If guild is not loaded.
* @throws PDOException On PDO operation error.
*/
public function setCustomField($field, $value)
{
if( !isset($this->data['id']) )
{
throw new E_OTS_NotLoaded();
}
// quotes value for SQL query
if(!( is_int($value) || is_float($value) ))
{
$value = $this->db->quote($value);
}
$this->db->query('UPDATE ' . $this->db->tableName('guilds') . ' SET ' . $this->db->fieldName($field) . ' = ' . $value . ' WHERE ' . $this->db->fieldName('id') . ' = ' . $this->data['id']);
}
/**
* @version 0.1.0
* @return array List of ranks.
* @throws E_OTS_NotLoaded If guild is not loaded.
* @deprecated 0.0.5 Use getGuildRanksList().
*/
public function getGuildRanks()
{
if( !isset($this->data['id']) )
{
throw new E_OTS_NotLoaded();
}
$guildRanks = array();
foreach( $this->db->query('SELECT ' . $this->db->fieldName('id') . ' FROM ' . $this->db->tableName('guild_ranks') . ' WHERE ' . $this->db->fieldName('guild_id') . ' = ' . $this->data['id'])->fetchAll() as $guildRank)
{
// creates new object
$object = new OTS_GuildRank();
$object->load($guildRank['id']);
$guildRanks[] = $object;
}
return $guildRanks;
}
/**
* List of ranks in guild.
*
* <p>
* In difference to {@link OTS_Guild::getGuildRanks() getGuildRanks() method} this method returns filtered {@link OTS_GuildRanks_List OTS_GuildRanks_List} object instead of array of {@link OTS_GuildRank OTS_GuildRank} objects. It is more effective since OTS_GuildRanks_List doesn't perform all rows loading at once.
* </p>
*
* <p>
* Note: Returned object is only prepared, but not initialised. When using as parameter in foreach loop it doesn't matter since it will return it's iterator, but if you will wan't to execute direct operation on that object you will need to call {@link OTS_Base_List::rewind() rewind() method} first.
* </p>
*
* @version 0.1.4
* @since 0.0.5
* @return OTS_GuildRanks_List List of ranks from current guild.
* @throws E_OTS_NotLoaded If guild is not loaded.
*/
public function getGuildRanksList()
{
if( !isset($this->data['id']) )
{
throw new E_OTS_NotLoaded();
}
// creates filter
$filter = new OTS_SQLFilter();
$filter->compareField('guild_id', (int) $this->data['id']);
// creates list object
$list = new OTS_GuildRanks_List();
$list->setFilter($filter);
return $list;
}
/**
* Returns list of invited players.
*
* <p>
* OTServ and it's database doesn't provide such feature like guild invitations. In order to use this mechanism you have to write own {@link IOTS_GuildAction invitations drivers} and assign it using {@link OTS_Guild::setInvitesDriver() setInvitesDriver() method}.
* </p>
*
* @return array List of invited players.
* @throws E_OTS_NotLoaded If guild is not loaded.
* @throws E_OTS_NoDriver If there is no invites driver assigned.
*/
public function listInvites()
{
if( !isset($this->data['id']) )
{
throw new E_OTS_NotLoaded();
}
if( !isset($this->invites) )
{
throw new E_OTS_NoDriver();
}
// driven action
return $this->invites->listRequests();
}
/**
* Invites player to guild.
*
* <p>
* OTServ and it's database doesn't provide such feature like guild invitations. In order to use this mechanism you have to write own {@link IOTS_GuildAction invitations drivers} and assign it using {@link OTS_Guild::setInvitesDriver() setInvitesDriver() method}.
* </p>
*
* @param OTS_Player Player to be invited.
* @throws E_OTS_NotLoaded If guild is not loaded.
* @throws E_OTS_NoDriver If there is no invites driver assigned.
*/
public function invite(OTS_Player $player)
{
if( !isset($this->data['id']) )
{
throw new E_OTS_NotLoaded();
}
if( !isset($this->invites) )
{
throw new E_OTS_NoDriver();
}
// driven action
return $this->invites->addRequest($player);
}
/**
* Deletes invitation for player to guild.
*
* <p>
* OTServ and it's database doesn't provide such feature like guild invitations. In order to use this mechanism you have to write own {@link IOTS_GuildAction invitations drivers} and assign it using {@link OTS_Guild::setInvitesDriver() setInvitesDriver() method}.
* </p>
*
* @param OTS_Player Player to be un-invited.
* @throws E_OTS_NotLoaded If guild is not loaded.
* @throws E_OTS_NoDriver If there is no invites driver assigned.
*/
public function deleteInvite(OTS_Player $player)
{
if( !isset($this->data['id']) )
{
throw new E_OTS_NotLoaded();
}
if( !isset($this->invites) )
{
throw new E_OTS_NoDriver();
}
// driven action
return $this->invites->deleteRequest($player);
}
/**
* Finalise invitation.
*
* <p>
* OTServ and it's database doesn't provide such feature like guild invitations. In order to use this mechanism you have to write own {@link IOTS_GuildAction invitations drivers} and assign it using {@link OTS_Guild::setInvitesDriver() setInvitesDriver() method}.
* </p>
*
* @param OTS_Player Player to be joined.
* @throws E_OTS_NotLoaded If guild is not loaded.
* @throws E_OTS_NoDriver If there is no invites driver assigned.
*/
public function acceptInvite(OTS_Player $player)
{
if( !isset($this->data['id']) )
{
throw new E_OTS_NotLoaded();
}
if( !isset($this->invites) )
{
throw new E_OTS_NoDriver();
}
// driven action
return $this->invites->submitRequest($player);
}
/**
* Returns list of players that requested membership.
*
* <p>
* OTServ and it's database doesn't provide such feature like membership requests. In order to use this mechanism you have to write own {@link IOTS_GuildAction requests drivers} and assign it using {@link OTS_Guild::setInvitesDriver() setRequestsDriver() method}.
* </p>
*
* @return array List of players.
* @throws E_OTS_NotLoaded If guild is not loaded.
* @throws E_OTS_NoDriver If there is no requests driver assigned.
*/
public function listRequests()
{
if( !isset($this->data['id']) )
{
throw new E_OTS_NotLoaded();
}
if( !isset($this->requests) )
{
throw new E_OTS_NoDriver();
}
// driven action
return $this->requests->listRequests();
}
/**
* Requests membership in guild for player player.
*
* <p>
* OTServ and it's database doesn't provide such feature like membership requests. In order to use this mechanism you have to write own {@link IOTS_GuildAction requests drivers} and assign it using {@link OTS_Guild::setInvitesDriver() setRequestsDriver() method}.
* </p>
*
* @param OTS_Player Player that requested membership.
* @throws E_OTS_NotLoaded If guild is not loaded.
* @throws E_OTS_NoDriver If there is no requests driver assigned.
*/
public function request(OTS_Player $player)
{
if( !isset($this->data['id']) )
{
throw new E_OTS_NotLoaded();
}
if( !isset($this->requests) )
{
throw new E_OTS_NoDriver();
}
// driven action
return $this->requests->addRequest($player);
}
/**
* Deletes request from player.
*
* <p>
* OTServ and it's database doesn't provide such feature like membership requests. In order to use this mechanism you have to write own {@link IOTS_GuildAction requests drivers} and assign it using {@link OTS_Guild::setInvitesDriver() setRequestsDriver() method}.
* </p>
*
* @param OTS_Player Player to be rejected.
* @throws E_OTS_NotLoaded If guild is not loaded.
* @throws E_OTS_NoDriver If there is no requests driver assigned.
*/
public function deleteRequest(OTS_Player $player)
{
if( !isset($this->data['id']) )
{
throw new E_OTS_NotLoaded();
}
if( !isset($this->requests) )
{
throw new E_OTS_NoDriver();
}
// driven action
return $this->requests->deleteRequest($player);
}
/**
* Accepts player.
*
* <p>
* OTServ and it's database doesn't provide such feature like membership requests. In order to use this mechanism you have to write own {@link IOTS_GuildAction requests drivers} and assign it using {@link OTS_Guild::setInvitesDriver() setRequestsDriver() method}.
* </p>
*
* @param OTS_Player Player to be accepted.
* @throws E_OTS_NotLoaded If guild is not loaded.
* @throws E_OTS_NoDriver If there is no requests driver assigned.
*/
public function acceptRequest(OTS_Player $player)
{
if( !isset($this->data['id']) )
{
throw new E_OTS_NotLoaded();
}
if( !isset($this->requests) )
{
throw new E_OTS_NoDriver();
}
// driven action
return $this->requests->submitRequest($player);
}
/**
* Deletes guild.
*
* @version 0.0.5
* @since 0.0.5
* @throws E_OTS_NotLoaded If guild is not loaded.
* @throws PDOException On PDO operation error.
*/
public function delete()
{
if( !isset($this->data['id']) )
{
throw new E_OTS_NotLoaded();
}
// deletes row from database
$this->db->query('DELETE FROM ' . $this->db->tableName('guilds') . ' WHERE ' . $this->db->fieldName('id') . ' = ' . $this->data['id']);
// resets object handle
unset($this->data['id']);
}
/**
* Returns ranks iterator.
*
* <p>
* There is no need to implement entire Iterator interface since we have {@link OTS_GuildRanks_List ranks list class} for it.
* </p>
*
* @version 0.0.5
* @since 0.0.5
* @throws E_OTS_NotLoaded If guild is not loaded.
* @throws PDOException On PDO operation error.
* @return Iterator List of ranks.
*/
public function getIterator()
{
return $this->getGuildRanksList();
}
/**
* Returns number of ranks within.
*
* @version 0.0.5
* @since 0.0.5
* @throws E_OTS_NotLoaded If guild is not loaded.
* @throws PDOException On PDO operation error.
* @return int Count of ranks.
*/
public function count()
{
return $this->getGuildRanksList()->count();
}
/**
* Magic PHP5 method.
*
* @version 0.1.3
* @since 0.1.0
* @param string $name Property name.
* @return mixed Property value.
* @throws OutOfBoundsException For non-supported properties.
* @throws PDOException On PDO operation error.
*/
public function __get($name)
{
switch($name)
{
case 'loaded':
return $this->isLoaded();
case 'id':
return $this->getId();
case 'name':
return $this->getName();
case 'owner':
return $this->getOwner();
case 'creationData':
return $this->getCreationData();
case 'guildRanksList':
return $this->getGuildRanksList();
case 'invites':
return $this->listInvites();
case 'requests':
return $this->listRequests();
default:
throw new OutOfBoundsException();
}
}
/**
* Magic PHP5 method.
*
* @version 0.1.0
* @since 0.1.0
* @param string $name Property name.
* @param mixed $value Property value.
* @throws E_OTS_NotLoaded If passed parameter for owner field won't be loaded.
* @throws OutOfBoundsException For non-supported properties.
*/
public function __set($name, $value)
{
switch($name)
{
case 'name':
$this->setName($value);
break;
case 'owner':
$this->setOwner($value);
break;
case 'creationData':
$this->setCreationData($value);
break;
case 'invitesDriver':
$this->setInvitesDriver($value);
break;
case 'requestsDriver':
$this->setRequestsDriver($value);
break;
default:
throw new OutOfBoundsException();
}
}
/**
* Returns string representation of object.
*
* <p>
* If any display driver is currently loaded then it uses it's method. Else it returns guild name.
* </p>
*
* @version 0.1.3
* @since 0.1.0
* @return string String representation of object.
*/
public function __toString()
{
$ots = POT::getInstance();
// checks if display driver is loaded
if( $ots->isDisplayDriverLoaded() )
{
return $ots->getDisplayDriver()->displayGuild($this);
}
return $this->getName();
}
}
/**#@-*/
?>

View File

@@ -0,0 +1,513 @@
<?php
/**#@+
* @version 0.0.4
* @since 0.0.4
*/
/**
* @package POT
* @version 0.1.4
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 - 2008 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/
/**
* OTServ guild rank abstraction.
*
* @package POT
* @version 0.1.4
* @property string $name Rank title.
* @property OTS_Guild $guild Guild in which rank exists.
* @property int $level Guild access level.
* @property-read bool $loaded Loaded state check.
* @property-read int $id Row ID.
* @property-read OTS_Players_List $playersList List of members with this rank.
*/
class OTS_GuildRank extends OTS_Row_DAO implements IteratorAggregate, Countable
{
/**
* Rank data.
*
* @var array
*/
private $data = array();
/**
* Loads rank with given id.
*
* @version 0.0.5
* @param int $id Rank's ID.
* @throws PDOException On PDO operation error.
*/
public function load($id)
{
// SELECT query on database
$this->data = $this->db->query('SELECT ' . $this->db->fieldName('id') . ', ' . $this->db->fieldName('guild_id') . ', ' . $this->db->fieldName('name') . ', ' . $this->db->fieldName('level') . ' FROM ' . $this->db->tableName('guild_ranks') . ' WHERE ' . $this->db->fieldName('id') . ' = ' . (int) $id)->fetch();
}
/**
* Loads rank by it's name.
*
* <p>
* As there can be several ranks with same name in different guilds you can pass optional second parameter to specify in which guild script should look for rank.
* </p>
*
* @version 0.0.5
* @param string $name Rank's name.
* @param OTS_Guild $guild Guild in which rank should be found.
* @throws PDOException On PDO operation error.
* @throws E_OTS_NotLoaded If given <var>$guild</var> object is not loaded.
*/
public function find($name, OTS_Guild $guild = null)
{
$where = '';
// additional guild id criterium
if( isset($guild) )
{
$where = ' AND ' . $this->db->fieldName('guild_id') . ' = ' . $guild->getId();
}
// finds player's ID
$id = $this->db->query('SELECT ' . $this->db->fieldName('id') . ' FROM ' . $this->db->tableName('guilds') . ' WHERE ' . $this->db->fieldName('name') . ' = ' . $this->db->quote($name) . $where)->fetch();
// if anything was found
if( isset($id['id']) )
{
$this->load($id['id']);
}
}
/**
* Checks if object is loaded.
*
* @return bool Load state.
*/
public function isLoaded()
{
return isset($this->data['id']);
}
/**
* Saves rank in database.
*
* <p>
* If rank is not loaded to represent any existing group it will create new row for it.
* </p>
*
* @version 0.0.8
* @throws PDOException On PDO operation error.
*/
public function save()
{
// updates existing rank
if( isset($this->data['id']) )
{
// UPDATE query on database
$this->db->query('UPDATE ' . $this->db->tableName('guild_ranks') . ' SET ' . $this->db->fieldName('guild_id') . ' = ' . $this->db->quote($this->data['guild_id']) . ', ' . $this->db->fieldName('name') . ' = ' . $this->db->quote($this->data['name']) . ', ' . $this->db->fieldName('level') . ' = ' . $this->data['level'] . ' WHERE ' . $this->db->fieldName('id') . ' = ' . $this->data['id']);
}
// creates new rank
else
{
// INSERT query on database
$this->db->query('INSERT INTO ' . $this->db->tableName('guild_ranks') . ' (' . $this->db->fieldName('guild_id') . ', ' . $this->db->fieldName('name') . ', ' . $this->db->fieldName('level') . ') VALUES (' . $this->data['guild_id'] . ', ' . $this->db->quote($this->data['name']) . ', ' . $this->data['level'] . ')');
// ID of new rank
$this->data['id'] = $this->db->lastInsertId();
}
}
/**
* Rank ID.
*
* @return int Rank ID.
* @throws E_OTS_NotLoaded If rank is not loaded.
*/
public function getId()
{
if( !isset($this->data['id']) )
{
throw new E_OTS_NotLoaded();
}
return $this->data['id'];
}
/**
* Rank name.
*
* @return string Rank's name.
* @throws E_OTS_NotLoaded If rank is not loaded.
*/
public function getName()
{
if( !isset($this->data['name']) )
{
throw new E_OTS_NotLoaded();
}
return $this->data['name'];
}
/**
* Sets rank's name.
*
* <p>
* This method only updates object state. To save changes in database you need to use {@link OTS_GuildRank::save() save() method} to flush changed to database.
* </p>
*
* @param string $name Name.
*/
public function setName($name)
{
$this->data['name'] = (string) $name;
}
/**
* Returns guild of this rank.
*
* @version 0.1.0
* @return OTS_Guild Guild of this rank.
* @throws E_OTS_NotLoaded If rank is not loaded.
* @throws PDOException On PDO operation error.
*/
public function getGuild()
{
if( !isset($this->data['guild_id']) )
{
throw new E_OTS_NotLoaded();
}
$guild = new OTS_Guild();
$guild->load($this->data['guild_id']);
return $guild;
}
/**
* Assigns rank to guild.
*
* <p>
* This method only updates object state. To save changes in database you need to use {@link OTS_GuildRank::save() save() method} to flush changed to database.
* </p>
*
* @param OTS_Guild $guild Owning guild.
* @throws E_OTS_NotLoaded If given <var>$guild</var> object is not loaded.
*/
public function setGuild(OTS_Guild $guild)
{
$this->data['guild_id'] = $guild->getId();
}
/**
* Rank's access level.
*
* @return int Rank access level within guild.
* @throws E_OTS_NotLoaded If rank is not loaded.
*/
public function getLevel()
{
if( !isset($this->data['level']) )
{
throw new E_OTS_NotLoaded();
}
return $this->data['level'];
}
/**
* Sets rank's access level within guild.
*
* <p>
* This method only updates object state. To save changes in database you need to use {@link OTS_GuildRank::save() save() method} to flush changed to database.
* </p>
*
* @param int $level access level within guild.
*/
public function setLevel($level)
{
$this->data['level'] = (int) $level;
}
/**
* Reads custom field.
*
* <p>
* Reads field by it's name. Can read any field of given record that exists in database.
* </p>
*
* <p>
* Note: You should use this method only for fields that are not provided in standard setters/getters (SVN fields). This method runs SQL query each time you call it so it highly overloads used resources.
* </p>
*
* @version 0.0.5
* @param string $field Field name.
* @return string Field value.
* @throws E_OTS_NotLoaded If rank is not loaded.
* @throws PDOException On PDO operation error.
*/
public function getCustomField($field)
{
if( !isset($this->data['id']) )
{
throw new E_OTS_NotLoaded();
}
$value = $this->db->query('SELECT ' . $this->db->fieldName($field) . ' FROM ' . $this->db->tableName('guild_ranks') . ' WHERE ' . $this->db->fieldName('id') . ' = ' . $this->data['id'])->fetch();
return $value[$field];
}
/**
* Writes custom field.
*
* <p>
* Write field by it's name. Can write any field of given record that exists in database.
* </p>
*
* <p>
* Note: You should use this method only for fields that are not provided in standard setters/getters (SVN fields). This method runs SQL query each time you call it so it highly overloads used resources.
* </p>
*
* <p>
* Note: Make sure that you pass $value argument of correct type. This method determinates whether to quote field value. It is safe - it makes you sure that no unproper queries that could lead to SQL injection will be executed, but it can make your code working wrong way. For example: $object->setCustomField('foo', '1'); will quote 1 as as string ('1') instead of passing it as a integer.
* </p>
*
* @version 0.0.5
* @param string $field Field name.
* @param mixed $value Field value.
* @throws E_OTS_NotLoaded If rank is not loaded.
* @throws PDOException On PDO operation error.
*/
public function setCustomField($field, $value)
{
if( !isset($this->data['id']) )
{
throw new E_OTS_NotLoaded();
}
// quotes value for SQL query
if(!( is_int($value) || is_float($value) ))
{
$value = $this->db->quote($value);
}
$this->db->query('UPDATE ' . $this->db->tableName('guild_ranks') . ' SET ' . $this->db->fieldName($field) . ' = ' . $value . ' WHERE ' . $this->db->fieldName('id') . ' = ' . $this->data['id']);
}
/**
* @version 0.1.0
* @return array List of members.
* @throws E_OTS_NotLoaded If rank is not loaded.
* @deprecated 0.0.5 Use getPlayersList().
*/
public function getPlayers()
{
if( !isset($this->data['id']) )
{
throw new E_OTS_NotLoaded();
}
$players = array();
foreach( $this->db->query('SELECT ' . $this->db->fieldName('id') . ' FROM ' . $this->db->tableName('players') . ' WHERE ' . $this->db->fieldName('rank_id') . ' = ' . $this->data['id'])->fetchAll() as $player)
{
// creates new object
$object = new OTS_Player();
$object->load($player['id']);
$players[] = $object;
}
return $players;
}
/**
* List of characters with current rank.
*
* <p>
* In difference to {@link OTS_GuildRank::getPlayers() getPlayers() method} this method returns filtered {@link OTS_Players_List OTS_Players_List} object instead of array of {@link OTS_Player OTS_Player} objects. It is more effective since OTS_Player_List doesn't perform all rows loading at once.
* </p>
*
* <p>
* Note: Returned object is only prepared, but not initialised. When using as parameter in foreach loop it doesn't matter since it will return it's iterator, but if you will wan't to execute direct operation on that object you will need to call {@link OTS_Base_List::rewind() rewind() method} first.
* </p>
*
* @version 0.1.4
* @since 0.0.5
* @return OTS_Players_List List of players with current rank.
* @throws E_OTS_NotLoaded If rank is not loaded.
*/
public function getPlayersList()
{
if( !isset($this->data['id']) )
{
throw new E_OTS_NotLoaded();
}
// creates filter
if(fieldExist('rank_id', 'players')) {
$filter = new OTS_SQLFilter();
$filter->compareField('rank_id', (int) $this->data['id']);
}
else {
$filter = new OTS_SQLFilter(new OTS_SQLField('rank_id', 'guild_membership'), OTS_SQLFilter::OPERATOR_EQUAL, $this->getID());
$filterPlayer = new OTS_SQLFilter(new OTS_SQLField('id', 'players'), OTS_SQLFilter::OPERATOR_EQUAL, new OTS_SQLField('player_id', 'guild_membership'));
}
$filter->compareField('deleted', 0);
// creates list object
$list = new OTS_Players_List();
$list->setFilter(new OTS_SQLFilter($filter, OTS_SQLFilter::CRITERIUM_AND, $filterPlayer));;
//$list->addOrder(new OTS_SQLOrder(new OTS_SQLField('name', 'players')));
return $list;
}
/**
* Deletes guild rank.
*
* @version 0.0.5
* @since 0.0.5
* @throws E_OTS_NotLoaded If guild rank is not loaded.
* @throws PDOException On PDO operation error.
*/
public function delete()
{
if( !isset($this->data['id']) )
{
throw new E_OTS_NotLoaded();
}
// deletes row from database
$this->db->query('DELETE FROM ' . $this->db->tableName('guild_ranks') . ' WHERE ' . $this->db->fieldName('id') . ' = ' . $this->data['id']);
// resets object handle
unset($this->data['id']);
}
/**
* Returns players iterator.
*
* <p>
* There is no need to implement entire Iterator interface since we have {@link OTS_Players_List players list class} for it.
* </p>
*
* @version 0.0.5
* @since 0.0.5
* @throws E_OTS_NotLoaded If rank is not loaded.
* @throws PDOException On PDO operation error.
* @return Iterator List of players.
*/
public function getIterator()
{
return $this->getPlayersList();
}
/**
* Returns number of player within.
*
* @version 0.0.5
* @since 0.0.5
* @throws E_OTS_NotLoaded If rank is not loaded.
* @throws PDOException On PDO operation error.
* @return int Count of players.
*/
public function count()
{
return $this->getPlayersList()->count();
}
/**
* Magic PHP5 method.
*
* @version 0.1.0
* @since 0.1.0
* @param string $name Property name.
* @return mixed Property value.
* @throws OutOfBoundsException For non-supported properties.
* @throws PDOException On PDO operation error.
*/
public function __get($name)
{
switch($name)
{
case 'loaded':
return $this->isLoaded();
case 'id':
return $this->getId();
case 'name':
return $this->getName();
case 'guild':
return $this->getGuild();
case 'level':
return $this->getLevel();
case 'playersList':
return $this->getPlayersList();
default:
throw new OutOfBoundsException();
}
}
/**
* Magic PHP5 method.
*
* @version 0.1.0
* @since 0.1.0
* @param string $name Property name.
* @param mixed $value Property value.
* @throws OutOfBoundsException For non-supported properties.
* @throws PDOException On PDO operation error.
*/
public function __set($name, $value)
{
switch($name)
{
case 'name':
$this->setName($value);
break;
case 'guild':
$this->setGuild($value);
break;
case 'level':
$this->setLevel($value);
break;
default:
throw new OutOfBoundsException();
}
}
/**
* Returns string representation of object.
*
* <p>
* If any display driver is currently loaded then it uses it's method. Else it returns rank name.
* </p>
*
* @version 0.1.3
* @since 0.1.0
* @return string String representation of object.
*/
public function __toString()
{
$ots = POT::getInstance();
// checks if display driver is loaded
if( $ots->isDisplayDriverLoaded() )
{
return $ots->getDisplayDriver()->displayGuildRank($this);
}
return $this->getName();
}
}
/**#@-*/
?>

View File

@@ -0,0 +1,76 @@
<?php
/**#@+
* @since 0.0.4
*/
/**
* @package POT
* @version 0.1.3
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 - 2008 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/
/**
* List of guild ranks.
*
* @package POT
* @version 0.1.3
*/
class OTS_GuildRanks_List extends OTS_Base_List
{
/**
* @version 0.0.5
* @param OTS_GuildRank $guildRank Rank to be deleted.
* @deprecated 0.0.5 Use OTS_GuildRank->delete().
*/
public function deleteGuildRank(OTS_GuildRank $guildRank)
{
$this->db->query('DELETE FROM ' . $this->db->tableName('guild_ranks') . ' WHERE ' . $this->db->fieldName('id') . ' = ' . $guildRank->getId() );
}
/**
* Sets list parameters.
*
* <p>
* This method is called at object creation.
* </p>
*
* @version 0.0.5
* @since 0.0.5
*/
public function init()
{
$this->table = 'guild_ranks';
$this->class = 'GuildRank';
}
/**
* Returns string representation of object.
*
* <p>
* If any display driver is currently loaded then it uses it's method.
* </p>
*
* @version 0.1.3
* @since 0.1.0
* @return string String representation of object.
*/
public function __toString()
{
$ots = POT::getInstance();
// checks if display driver is loaded
if( $ots->isDisplayDriverLoaded() )
{
return $ots->getDisplayDriver()->displayGuildRanksList($this);
}
return (string) $this->count();
}
}
/**#@-*/
?>

View File

@@ -0,0 +1,76 @@
<?php
/**#@+
* @since 0.0.4
*/
/**
* @package POT
* @version 0.1.3
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 - 2008 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/
/**
* List of guilds.
*
* @package POT
* @version 0.1.3
*/
class OTS_Guilds_List extends OTS_Base_List
{
/**
* @version 0.0.5
* @param OTS_Guild $guild Guild to be deleted.
* @deprecated 0.0.5 Use OTS_Guild->delete().
*/
public function deleteGuild(OTS_Guild $guild)
{
$this->db->query('DELETE FROM ' . $this->db->tableName('guilds') . ' WHERE ' . $this->db->fieldName('id') . ' = ' . $account->getId() );
}
/**
* Sets list parameters.
*
* <p>
* This method is called at object creation.
* </p>
*
* @version 0.0.5
* @since 0.0.5
*/
public function init()
{
$this->table = 'guilds';
$this->class = 'Guild';
}
/**
* Returns string representation of object.
*
* <p>
* If any display driver is currently loaded then it uses it's method.
* </p>
*
* @version 0.1.3
* @since 0.1.0
* @return string String representation of object.
*/
public function __toString()
{
$ots = POT::getInstance();
// checks if display driver is loaded
if( $ots->isDisplayDriverLoaded() )
{
return $ots->getDisplayDriver()->displayGuildsList($this);
}
return (string) $this->count();
}
}
/**#@-*/
?>

View File

@@ -0,0 +1,430 @@
<?php
/**#@+
* @version 0.1.0
* @since 0.1.0
*/
/**
* @package POT
* @version 0.1.3
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 - 2008 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/
/**
* Wrapper for house information.
*
* <p>
* Unlike other {@link OTS_Base_DAO OTS_Base_DAO} child classes, OTS_House bases not only on database, but also loads some additional info from XML DOM node. It can't be load - it is always initialised with {@link http://www.php.net/manual/en/ref.dom.php DOMElement} object. Saving will only update database row - won't change XML data. Same about using {@link OTS_House::delete() delete() method}.
* </p>
*
* @package POT
* @version 0.1.3
* @property OTS_Player $owner House owner.
* @property int $paid Paid time.
* @property int $warnings Warnings message.
* @property-read int $id House ID.
* @property-read string $name House name.
* @property-read int $townId ID of town where house is located.
* @property-read string $townName Name of town where house is located.
* @property-read int $rent Rent cost.
* @property-read int $size House size.
* @property-read OTS_MapCoords $entry Entry point.
* @property-read array $tiles List of tile points which house uses.
*/
class OTS_House extends OTS_Base_DAO
{
/**
* House rent info.
*
* @var array
*/
private $data = array();
/**
* Information handler.
*
* @var DOMElement
*/
private $element;
/**
* Tiles list.
*
* @var array
*/
private $tiles = array();
/**
* Creates wrapper for given house element.
*
* @param DOMElement $element House information.
* @throws PDOException On PDO operation error.
*/
public function __construct(DOMElement $element)
{
parent::__construct();
$this->element = $element;
// loads SQL part - `id` field is not needed as we have it from XML
$this->data = $this->db->query('SELECT ' . $this->db->fieldName('owner') . ', ' . $this->db->fieldName('paid') . ', ' . $this->db->fieldName('warnings') . ' FROM ' . $this->db->tableName('houses') . ' WHERE ' . $this->db->fieldName('id') . ' = ' . $this->getId() )->fetch();
}
/**
* Magic PHP5 method.
*
* <p>
* Allows object serialisation.
* </p>
*
* @return array List of properties that should be saved.
*/
public function __sleep()
{
return array('data', 'element');
}
/**
* Saves info in database.
*
* @throws PDOException On PDO operation error.
*/
public function save()
{
// inserts new record
if( empty($this->data) )
{
$this->db->query('INSERT INTO ' . $this->db->tableName('houses') . ' (' . $this->db->fieldName('id') . ', ' . $this->db->fieldName('owner') . ', ' . $this->db->fieldName('paid') . ', ' . $this->db->fieldName('warnings') . ') VALUES (' . $this->getId() . ', ' . $this->data['owner'] . ', ' . $this->data['paid'] . ', ' . $this->data['warnings'] . ')');
}
// updates previous one
else
{
$this->db->query('UPDATE ' . $this->db->tableName('houses') . ' SET ' . $this->db->fieldName('id') . ' = ' . $this->getId() . ', ' . $this->db->fieldName('owner') . ' = ' . $this->data['owner'] . ', ' . $this->db->fieldName('paid') . ' = ' . $this->data['paid'] . ', ' . $this->db->fieldName('warnings') . ' = ' . $this->data['warnings'] . ' WHERE ' . $this->db->fieldName('id') . ' = ' . $this->getId() );
}
}
/**
* Deletes house info from database.
*
* @throws PDOException On PDO operation error.
*/
public function delete()
{
// deletes row from database
$this->db->query('DELETE FROM ' . $this->db->tableName('houses') . ' WHERE ' . $this->db->fieldName('id') . ' = ' . $this->data['id']);
// resets object handle
$this->data = array();
}
/**
* Returns house's ID.
*
* @return int House ID.
* @throws DOMException On DOM operation error.
*/
public function getId()
{
return (int) $this->element->getAttribute('houseid');
}
/**
* Return house's name.
*
* @return string House name.
* @throws DOMException On DOM operation error.
*/
public function getName()
{
return $this->element->getAttribute('name');
}
/**
* Returns town ID in which house is located.
*
* @return int Town ID.
* @throws DOMException On DOM operation error.
*/
public function getTownId()
{
return (int) $this->element->getAttribute('townid');
}
/**
* Returns town name.
*
* @return string Town name.
* @throws E_OTS_NotLoaded When map file is not loaded to fetch towns names.
*/
public function getTownName()
{
return POT::getInstance()->getMap()->getTownName( $this->getTownId() );
}
/**
* Returns house rent cost.
*
* @return int Rent cost.
* @throws DOMException On DOM operation error.
*/
public function getRent()
{
return (int) $this->element->getAttribute('rent');
}
/**
* Returns house size.
*
* @return int House size.
* @throws DOMException On DOM operation error.
*/
public function getSize()
{
return (int) $this->element->getAttribute('size');
}
/**
* Returns entry position.
*
* @return OTS_MapCoords Entry coordinations on map.
*/
public function getEntry()
{
return new OTS_MapCoords( (int) $this->element->getAttribute('entryx'), (int) $this->element->getAttribute('entryy'), (int) $this->element->getAttribute('entryz') );
}
/**
* Returns current house owner.
*
* @return OTS_Player|null Player that currently owns house (null if there is no owner).
*/
public function getOwner()
{
if( isset($this->data['owner']) && $this->data['owner'] != 0)
{
$player = new OTS_Player();
$player->load($this->data['owner']);
return $player;
}
// not rent
else
{
return null;
}
}
/**
* Sets house owner.
*
* <p>
* This method only updates object state. To save changes in database you need to use {@link OTS_House::save() save() method} to flush changed to database.
* </p>
*
* @param OTS_Player $player House owner to be set.
* @throws E_OTS_NotLoaded If given <var>$player</var> object is not loaded.
*/
public function setOwner(OTS_Player $player)
{
$this->data['owner'] = $player->getId();
}
/**
* Returns paid date.
*
* @return int|false Date timestamp until which house is rent (false if none).
*/
public function getPaid()
{
if( isset($this->data['paid']) )
{
return $this->data['paid'];
}
// not rent
else
{
return false;
}
}
/**
* Sets paid date.
*
* <p>
* This method only updates object state. To save changes in database you need to use {@link OTS_House::save() save() method} to flush changed to database.
* </p>
*
* @param int $paid Sets paid timestamp to passed one.
*/
public function setPaid($paid)
{
$this->data['paid'] = $paid;
}
/**
* Returns house warnings.
*
* @version 0.1.2
* @return int|false Warnings text (false if none).
*/
public function getWarnings()
{
if( isset($this->data['warnings']) )
{
return $this->data['warnings'];
}
// not rent
else
{
return false;
}
}
/**
* Sets house warnings.
*
* <p>
* This method only updates object state. To save changes in database you need to use {@link OTS_House::save() save() method} to flush changed to database.
* </p>
*
* @version 0.1.2
* @param int $warnings Sets house warnings.
*/
public function setWarnings($warnings)
{
$this->data['warnings'] = (int) $warnings;
}
/**
* Adds tile to house.
*
* @param OTS_MapCoords $tile Tile to be added.
*/
public function addTile(OTS_MapCoords $tile)
{
$this->tiles[] = $tile;
}
/**
* Returns tiles list.
*
* <p>
* This returns list of coords of tiles used by this house on map. It will succeed only if house object was created during map loading with houses file opened to assign loaded tiles.
* </p>
*
* @return array List of tiles.
*/
public function getTiles()
{
return $this->tiles;
}
/**
* Magic PHP5 method.
*
* @param string $name Property name.
* @return mixed Property value.
* @throws E_OTS_NotLoaded When atempt to read info about map while map not being loaded.
* @throws OutOfBoundsException For non-supported properties.
* @throws DOMException On DOM operation error.
*/
public function __get($name)
{
switch($name)
{
case 'id':
return $this->getId();
case 'name':
return $this->getName();
case 'townId':
return $this->getTownId();
case 'townName':
return $this->getTownName();
case 'rent':
return $this->getRent();
case 'size':
return $this->getSize();
case 'entry':
return $this->getEntry();
case 'owner':
return $this->getOwner();
case 'paid':
return $this->getPaid();
case 'warnings':
return $this->getWarnings();
case 'tiles':
return $this->getTiles();
default:
throw new OutOfBoundsException();
}
}
/**
* Magic PHP5 method.
*
* @param string $name Property name.
* @param mixed $value Property value.
* @throws E_OTS_NotLoaded If passed parameter for owner field won't be loaded.
* @throws OutOfBoundsException For non-supported properties.
*/
public function __set($name, $value)
{
switch($name)
{
case 'owner':
$this->setOwner($value);
break;
case 'paid':
$this->setPaid($value);
break;
case 'warnings':
$this->setWarnings($values);
break;
default:
throw new OutOfBoundsException();
}
}
/**
* Returns string representation of object.
*
* <p>
* If any display driver is currently loaded then it uses it's method. Otherwise just returns house ID.
* </p>
*
* @version 0.1.3
* @since 0.1.3
* @return string String representation of object.
*/
public function __toString()
{
$ots = POT::getInstance();
// checks if display driver is loaded
if( $ots->isDataDisplayDriverLoaded() )
{
return $ots->getDataDisplayDriver()->displayHouse($this);
}
return $this->getId();
}
}
/**#@-*/
?>

View File

@@ -0,0 +1,255 @@
<?php
/**#@+
* @version 0.1.0
* @since 0.1.0
*/
/**
* @package POT
* @version 0.1.3
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 - 2008 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/
/**
* Wrapper for houses list.
*
* @package POT
* @version 0.1.3
* @tutorial POT/data_directory.pkg#towns.houses
*/
class OTS_HousesList implements IteratorAggregate, Countable, ArrayAccess
{
/**
* List of houses elements.
*
* @var array
*/
private $houses = array();
/**
* Loads houses information.
*
* @version 0.1.3
* @param string $path Houses file.
* @throws DOMException On DOM operation error.
*/
public function __construct($path)
{
$houses = new DOMDocument();
$houses->load($path);
foreach( $houses->getElementsByTagName('house') as $house)
{
$this->houses[ (int) $house->getAttribute('houseid') ] = new OTS_House($house);
}
}
/**
* Magic PHP5 method.
*
* <p>
* Allows object importing from {@link http://www.php.net/manual/en/function.var-export.php var_export()}.
* </p>
*
* @param array $properties List of object properties.
* @throws DOMException On DOM operation error.
*/
public function __set_state($properties)
{
$object = new self();
// loads properties
foreach($properties as $name => $value)
{
$object->$name = $value;
}
return $object;
}
/**
* Checks if given house exists on list.
*
* @version 0.1.3
* @since 0.1.3
* @param string $name Name.
* @return bool If house is set then true.
*/
public function hasHouse($name)
{
foreach($this->houses as $id => $house)
{
// checks houses id
if( $house->getName() == $name)
{
return true;
}
}
return false;
}
/**
* Returns house information.
*
* @version 0.1.3
* @param int $id House ID.
* @return OTS_House House information wrapper.
* @throws OutOfBoundsException If house was not found.
*/
public function getHouse($id)
{
if( isset($this->houses[$id]) )
{
return $this->houses[$id];
}
throw new OutOfBoundsException();
}
/**
* Checks if given house ID exists on list.
*
* @version 0.1.3
* @since 0.1.3
* @param int $id ID.
* @return bool If house is set then true.
*/
public function hasHouseId($id)
{
return isset($this->houses[$id]);
}
/**
* Returns ID of house with given name.
*
* @version 0.1.3
* @param string $name House name.
* @return int House ID.
* @throws OutOfBoundsException False if not found.
*/
public function getHouseId($name)
{
foreach($this->houses as $id => $house)
{
// checks houses id
if( $house->getName() == $name)
{
return $id;
}
}
throw new OutOfBoundsException();
}
/**
* Returns amount of houses.
*
* @return int Count of houses.
*/
public function count()
{
return count($this->houses);
}
/**
* Returns iterator handle for loops.
*
* @return ArrayIterator Houses list iterator.
*/
public function getIterator()
{
return new ArrayIterator($this->houses);
}
/**
* Checks if given element exists.
*
* @param string|int $offset Array key.
* @return bool True if it's set.
*/
public function offsetExists($offset)
{
// integer key
if( is_int($offset) )
{
return isset($this->houses[$offset]);
}
// house name
return $this->hasHouse($offset);
}
/**
* Returns item from given position.
*
* @version 0.1.3
* @param string|int $offset Array key.
* @return OTS_House|int If key is an integer (type-sensitive!) then returns house instance. If it's a string then return associated ID found by house name.
*/
public function offsetGet($offset)
{
// integer key
if( is_int($offset) )
{
return $this->getHouse($offset);
}
// house name
return $this->getHouseId($offset);
}
/**
* This method is implemented for ArrayAccess interface. In fact you can't write/append to houses list. Any call to this method will cause {@link E_OTS_ReadOnly E_OTS_ReadOnly} raise.
*
* @param string|int $offset Array key.
* @param mixed $value Field value.
* @throws E_OTS_ReadOnly Always - this class is read-only.
*/
public function offsetSet($offset, $value)
{
throw new E_OTS_ReadOnly();
}
/**
* This method is implemented for ArrayAccess interface. In fact you can't write/append to houses list. Any call to this method will cause {@link E_OTS_ReadOnly E_OTS_ReadOnly} raise.
*
* @param string|int $offset Array key.
* @throws E_OTS_ReadOnly Always - this class is read-only.
*/
public function offsetUnset($offset)
{
throw new E_OTS_ReadOnly();
}
/**
* Returns string representation of object.
*
* <p>
* If any display driver is currently loaded then it uses it's method.
* </p>
*
* @version 0.1.3
* @since 0.1.3
* @return string String representation of object.
*/
public function __toString()
{
$ots = POT::getInstance();
// checks if display driver is loaded
if( $ots->isDataDisplayDriverLoaded() )
{
return $ots->getDataDisplayDriver()->displayHousesList($this);
}
return (string) $this->count();
}
}
/**#@-*/
?>

View File

@@ -0,0 +1,63 @@
<?php
/**
* @package POT
* @version 0.1.5
* @since 0.1.5
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 - 2008 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/
/**
* OTServ IP ban.
*
* @package POT
* @version 0.1.5
* @since 0.1.5
*/
class OTS_IPBan extends OTS_Ban
{
/**
* Ban data.
*
* @var array
* @version 0.1.5
* @since 0.1.5
*/
private $data = array('type' => POT::BAN_IP, 'param' => 0, 'active' => true, 'admin_id' => 0, 'comment' => '', 'reason' => 0);
/**
* Loads IP ban with given id.
*
* @version 0.1.5
* @since 0.1.5
* @param int $id Ban ID.
* @throws PDOException On PDO operation error.
*/
public function load($id)
{
// SELECT query on database
$this->data = $this->db->query('SELECT ' . $this->db->fieldName('id') . ', ' . $this->db->fieldName('type') . ', ' . $this->db->fieldName('value') . ', ' . $this->db->fieldName('param') . ', ' . $this->db->fieldName('active') . ', ' . $this->db->fieldName('expires') . ', ' . $this->db->fieldName('added') . ', ' . $this->db->fieldName('admin_id') . ', ' . $this->db->fieldName('comment') . ', ' . $this->db->fieldName('reason') . ' FROM ' . $this->db->tableName('bans') . ' WHERE ' . $this->db->fieldName('type') . ' = ' . POT::BAN_IP . ' AND ' . $this->db->fieldName('id') . ' = ' . (int) $id)->fetch();
}
/**
* Loads IP ban by banned IP.
*
* <p>
* This method loads ban that matches given IP (including mask). To unban IP you should rather use {@link OTS_IPBan::load() load() method} to load exacly that ban that you are seeking for.
* </p>
*
* @version 0.1.5
* @since 0.1.5
* @param int $ip IP.
* @throws PDOException On PDO operation error.
*/
public function find($ip)
{
// SELECT query on database
$this->data = $this->db->query('SELECT ' . $this->db->fieldName('id') . ', ' . $this->db->fieldName('type') . ', ' . $this->db->fieldName('value') . ', ' . $this->db->fieldName('param') . ', ' . $this->db->fieldName('active') . ', ' . $this->db->fieldName('expires') . ', ' . $this->db->fieldName('added') . ', ' . $this->db->fieldName('admin_id') . ', ' . $this->db->fieldName('comment') . ', ' . $this->db->fieldName('reason') . ' FROM ' . $this->db->tableName('bans') . ' WHERE ' . $this->db->fieldName('type') . ' = ' . POT::BAN_IP . ' AND ' . $this->db->fieldName('value') . ' & ' . $this->db->fieldName('param') . ' = ' . (int) $ip . ' & ' . $this->db->fieldName('param') )->fetch();
}
}
?>

View File

@@ -0,0 +1,38 @@
<?php
/**
* @package POT
* @version 0.1.5
* @since 0.1.5
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 - 2008 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/
/**
* List of IP bans.
*
* @package POT
* @version 0.1.5
* @since 0.1.5
*/
class OTS_IPBans_List extends OTS_Bans_List
{
/**
* Initializes list with IP bans filtering.
*
* @version 0.1.5
* @since 0.1.5
*/
public function __construct()
{
parent::__construct();
// filters only account bans
$filter = new OTS_SQLFilter();
$filter->addFilter( new OTS_SQLField('type', 'bans'), POT::BAN_IP);
$this->setFilter($filter);
}
}
?>

View File

@@ -0,0 +1,391 @@
<?php
/**#@+
* @version 0.0.2
* @since 0.0.2
*/
/**
* @package POT
* @version 0.1.0
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/
/**
* Wrapper for 'info' respond's DOMDocument.
*
* <p>
* Note: as this class extends DOMDocument class and contains exacly respond XML tree you can work on it as on normal DOM tree.
* </p>
*
* @package POT
* @version 0.1.0
* @property-read string $tspqVersion Root element version.
* @property-read int $uptime Uptime.
* @property-read string $ip IP number.
* @property-read string $name Server name.
* @property-read int $port Server port.
* @property-read string $location Server physical location.
* @property-read string $url Website URL.
* @property-read string $server What the hell...?
* @property-read string $serverVersion Server version.
* @property-read string $clientVersion Client version.
* @property-read string $owner Owner name.
* @property-read string $eMail Owner's e-mail.
* @property-read int $onlinePlayers Players online count.
* @property-read int $maxPlayers Maximum allowed players count.
* @property-read int $playersPeak Record of players online.
* @property-read int $monstersCount Number of monsters on map.
* @property-read string $mapName Map name.
* @property-read string $mapAuthor Map author.
* @property-read int $mapWidth Map width.
* @property-read int $mapHeight Map height.
* @property-read string $motd Message Of The Day.
*/
class OTS_InfoRespond extends DOMDocument
{
/**
* Returns version of root element.
*
* @return string TSPQ version.
* @throws DOMException On DOM operation error.
*/
public function getTSPQVersion()
{
return $this->documentElement->getAttribute('version');
}
/**
* Returns server uptime.
*
* @return int Uptime.
* @throws DOMException On DOM operation error.
*/
public function getUptime()
{
return (int) $this->documentElement->getElementsByTagName('serverinfo')->item(0)->getAttribute('uptime');
}
/**
* Returns server IP.
*
* @return string IP.
* @throws DOMException On DOM operation error.
*/
public function getIP()
{
return $this->documentElement->getElementsByTagName('serverinfo')->item(0)->getAttribute('ip');
}
/**
* Returns server name.
*
* @return string Name.
* @throws DOMException On DOM operation error.
*/
public function getName()
{
return $this->documentElement->getElementsByTagName('serverinfo')->item(0)->getAttribute('servername');
}
/**
* Returns server port.
*
* @return int Port.
* @throws DOMException On DOM operation error.
*/
public function getPort()
{
return (int) $this->documentElement->getElementsByTagName('serverinfo')->item(0)->getAttribute('port');
}
/**
* Returns server location.
*
* @return string Location.
* @throws DOMException On DOM operation error.
*/
public function getLocation()
{
return $this->documentElement->getElementsByTagName('serverinfo')->item(0)->getAttribute('location');
}
/**
* Returns server website.
*
* @return string Website URL.
* @throws DOMException On DOM operation error.
*/
public function getURL()
{
return $this->documentElement->getElementsByTagName('serverinfo')->item(0)->getAttribute('url');
}
/**
* Returns server attribute.
*
* I have no idea what the hell is it representing :P.
*
* @return string Attribute value.
* @throws DOMException On DOM operation error.
*/
public function getServer()
{
return $this->documentElement->getElementsByTagName('serverinfo')->item(0)->getAttribute('server');
}
/**
* Returns server version.
*
* @return string Version.
* @throws DOMException On DOM operation error.
*/
public function getServerVersion()
{
return $this->documentElement->getElementsByTagName('serverinfo')->item(0)->getAttribute('version');
}
/**
* Returns dedicated version of client.
*
* @return string Version.
* @throws DOMException On DOM operation error.
*/
public function getClientVersion()
{
return $this->documentElement->getElementsByTagName('serverinfo')->item(0)->getAttribute('client');
}
/**
* Returns owner name.
*
* @return string Owner name.
* @throws DOMException On DOM operation error.
*/
public function getOwner()
{
return $this->documentElement->getElementsByTagName('owner')->item(0)->getAttribute('name');
}
/**
* Returns owner e-mail.
*
* @return string Owner e-mail.
* @throws DOMException On DOM operation error.
*/
public function getEMail()
{
return $this->documentElement->getElementsByTagName('owner')->item(0)->getAttribute('email');
}
/**
* Returns current amount of players online.
*
* @return int Count of players.
* @throws DOMException On DOM operation error.
*/
public function getOnlinePlayers()
{
return (int) $this->documentElement->getElementsByTagName('players')->item(0)->getAttribute('online');
}
/**
* Returns maximum amount of players online.
*
* @return int Maximum allowed count of players.
* @throws DOMException On DOM operation error.
*/
public function getMaxPlayers()
{
return (int) $this->documentElement->getElementsByTagName('players')->item(0)->getAttribute('max');
}
/**
* Returns record of online players.
*
* @return int Players online record.
* @throws DOMException On DOM operation error.
*/
public function getPlayersPeak()
{
return (int) $this->documentElement->getElementsByTagName('players')->item(0)->getAttribute('peak');
}
/**
* Returns number of all monsters on map.
*
* @return int Count of monsters.
* @throws DOMException On DOM operation error.
*/
public function getMonstersCount()
{
return (int) $this->documentElement->getElementsByTagName('monsters')->item(0)->getAttribute('total');
}
/**
* Returns map name.
*
* @return string Map name.
* @throws DOMException On DOM operation error.
*/
public function getMapName()
{
return $this->documentElement->getElementsByTagName('map')->item(0)->getAttribute('name');
}
/**
* Returns map author.
*
* @return string Mapper name.
* @throws DOMException On DOM operation error.
*/
public function getMapAuthor()
{
return $this->documentElement->getElementsByTagName('map')->item(0)->getAttribute('author');
}
/**
* Returns map width.
*
* @return int Map width.
* @throws DOMException On DOM operation error.
*/
public function getMapWidth()
{
return (int) $this->documentElement->getElementsByTagName('map')->item(0)->getAttribute('width');
}
/**
* Returns map height.
*
* @return int Map height.
* @throws DOMException On DOM operation error.
*/
public function getMapHeight()
{
return (int) $this->documentElement->getElementsByTagName('map')->item(0)->getAttribute('height');
}
/**
* Returns server's Message Of The Day
*
* @version 0.1.0
* @return string Server MOTD.
* @throws DOMException On DOM operation error.
*/
public function getMOTD()
{
// look for text node child
foreach( $this->documentElement->getElementsByTagName('motd')->item(0)->childNodes as $child)
{
if($child->nodeType == XML_TEXT_NODE)
{
// found
return $child->nodeValue;
}
}
// strange...
return '';
}
/**
* Magic PHP5 method.
*
* @version 0.1.0
* @since 0.1.0
* @param string $name Property name.
* @return mixed Property value.
* @throws OutOfBoundsException For non-supported properties.
* @throws DOMException On DOM operation error.
*/
public function __get($name)
{
switch($name)
{
case 'tspqVersion':
return $this->getTSPQVersion();
case 'uptime':
return $this->getUptime();
case 'ip':
return $this->getIP();
case 'name':
return $this->getName();
case 'port':
return $this->getPort();
case 'location':
return $this->getLocation();
case 'url':
return $this->getURL();
case 'server':
return $this->getServer();
case 'serverVersion':
return $this->getServerVersion();
case 'clientVersion':
return $this->getClientVersion();
case 'owner':
return $this->getOwner();
case 'eMail':
return $this->getEMail();
case 'onlinePlayers':
return $this->getOnlinePlayers();
case 'maxPlayers':
return $this->getMaxPlayers();
case 'playersPeak':
return $this->getPlayersPeak();
case 'monstersCount':
return $this->getMonstersCount();
case 'mapName':
return $this->getMapName();
case 'mapAuthor':
return $this->getMapAuthor();
case 'mapWidth':
return $this->getMapWidth();
case 'mapHeight':
return $this->getMapHeight();
case 'motd':
return $this->getMOTD();
default:
throw new OutOfBoundsException();
}
}
/**
* Returns string representation of XML.
*
* @version 0.1.0
* @since 0.1.0
* @return string String representation of object.
*/
public function __toString()
{
return $this->saveXML();
}
}
/**#@-*/
?>

View File

@@ -0,0 +1,196 @@
<?php
/**#@+
* @version 0.0.3
* @since 0.0.3
*/
/**
* @package POT
* @version 0.1.0
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 - 2008 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/
/**
* Single item representation.
*
* <p>
* This class represents item that player has. It has no information about item feature, just it's handle in database. To get information about item type and it's features you have to use {@link OTS_ItemType OTS_ItemType class} - you can get it's object by calling {@link OTS_Item::getItemType() getItemType() method}, however you need to have global item types list loaded.
* </p>
*
* @package POT
* @version 0.1.0
* @property int $count Amount of item.
* @property string $attributes Attributes binary string.
* @property-read int $id Item type ID.
* @property-read OTS_ItemType $itemType Item type instance.
*/
class OTS_Item implements Countable
{
/**
* Item ID.
*
* @var int
*/
private $id;
/**
* Item count.
*
* @var int
*/
private $count = 0;
/**
* Additional attributes.
*
* @var string
*/
private $attributes;
/**
* Creates item of given ID.
*
* @param int $id Item ID.
*/
public function __construct($id)
{
$this->id = $id;
}
/**
* Returns item type.
*
* @return int Item ID.
*/
public function getId()
{
return $this->id;
}
/**
* Returns count of item.
*
* @return int Count of item.
*/
public function getCount()
{
return $this->count;
}
/**
* Sets count of item.
*
* @param int $count Count.
*/
public function setCount($count)
{
$this->count = (int) $count;
}
/**
* Returns item custom attributes.
*
* @return string Attributes.
*/
public function getAttributes()
{
return $this->attributes;
}
/**
* Sets item attributes.
*
* @param string $attributes Item Attributes.
*/
public function setAttributes($attributes)
{
$this->attributes = (string) $attributes;
}
/**
* Returns type of item.
*
* @version 0.1.0
* @since 0.1.0
* @return OTS_ItemType Returns item type of item (null if not exists).
* @throws E_OTS_NotLoaded If global items list wasn't loaded.
*/
public function getItemType()
{
return POT::getInstance()->getItemsList()->getItemType($this->id);
}
/**
* Count value for current item.
*
* @return int Count of item.
*/
public function count()
{
return $this->count;
}
/**
* Magic PHP5 method.
*
* @version 0.1.0
* @since 0.1.0
* @param string $name Property name.
* @return mixed Property value.
* @throws OutOfBoundsException For non-supported properties.
* @throws E_OTS_NotLoaded If global items list wasn't loaded.
*/
public function __get($name)
{
switch($name)
{
case 'count':
return $this->getCount();
case 'attributes':
return $this->getAttributes();
case 'id':
return $this->getId();
case 'itemType':
return $this->getItemType();
default:
throw new OutOfBoundsException();
}
}
/**
* Magic PHP5 method.
*
* @version 0.1.0
* @since 0.1.0
* @param string $name Property name.
* @param mixed $value Property value.
* @throws OutOfBoundsException For non-supported properties.
*/
public function __set($name, $value)
{
switch($name)
{
case 'count':
$this->setCount($value);
break;
case 'attributes':
$this->setAttributes($value);
break;
default:
throw new OutOfBoundsException();
}
}
}
/**#@-*/
?>

View File

@@ -0,0 +1,746 @@
<?php
/**#@+
* @version 0.0.8
* @since 0.0.8
*/
/**
* Code in this file bases on oryginal OTServ items loading C++ code (items.cpp, items.h).
*
* @package POT
* @version 0.1.3
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 - 2008 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/
/**
* Item type info.
*
* <p>
* This class represents only item type information. You can't assign it to player. To do that, you need to create instance of this item type (you can use {@link OTS_ItemType::createItem() createItem() method} to do that).
* </p>
*
* @package POT
* @version 0.1.3
* @property int $clientId Client ID.
* @property string $name Item name.
* @property int $group Group.
* @property int $type Item type.
* @property-read int $id Item type ID.
* @property-read array $attributesList List of all attributes.
* @property-read bool $blocking Is item blocking move.
* @property-read bool $hasHeight Does item have height.
* @property-read bool $usable Is item usable.
* @property-read bool $pickupable Is player able to pick it up.
* @property-read bool $movable Can be moved.
* @property-read bool $stackable Can be stacked.
* @property-read bool $alwaysOnTop Is always on top of stack.
* @property-read bool $readable Has readable sign.
* @property-read bool $rotable Can be rotated.
* @property-read bool $hangable Can be hang.
* @property-read bool $vertical Is verticaly oriented.
* @property-read bool $horizontal Is horizontaly oriented.
* @property-write int $flags Special flags.
*/
class OTS_ItemType
{
/**
* No group speciffied.
*/
const ITEM_GROUP_NONE = 0;
/**
* Ground tile.
*/
const ITEM_GROUP_GROUND = 1;
/**
* Container.
*/
const ITEM_GROUP_CONTAINER = 2;
/**
* Weapon.
*/
const ITEM_GROUP_WEAPON = 3;
/**
* Ammunition.
*/
const ITEM_GROUP_AMMUNITION = 4;
/**
* Armor.
*/
const ITEM_GROUP_ARMOR = 5;
/**
* Rune.
*/
const ITEM_GROUP_RUNE = 6;
/**
* Teleport field.
*/
const ITEM_GROUP_TELEPORT = 7;
/**
* Magic field.
*/
const ITEM_GROUP_MAGICFIELD = 8;
/**
* Item that can store editable sign.
*/
const ITEM_GROUP_WRITEABLE = 9;
/**
* Key.
*/
const ITEM_GROUP_KEY = 10;
/**
* Splash effect.
*/
const ITEM_GROUP_SPLASH = 11;
/**
* Liquid thing.
*/
const ITEM_GROUP_FLUID = 12;
/**
* Door.
*/
const ITEM_GROUP_DOOR = 13;
/**
* Deprecated item.
*
* @version 0.1.0
* @since 0.1.0
*/
const ITEM_GROUP_DEPRECATED = 14;
/**
* No special type.
*/
const ITEM_TYPE_NONE = 0;
/**
* Depot locker.
*/
const ITEM_TYPE_DEPOT = 1;
/**
* Mailbox.
*/
const ITEM_TYPE_MAILBOX = 2;
/**
* Trash can.
*/
const ITEM_TYPE_TRASHHOLDER = 3;
/**
* Container.
*/
const ITEM_TYPE_CONTAINER = 4;
/**
* Door.
*/
const ITEM_TYPE_DOOR = 5;
/**
* Magic field.
*/
const ITEM_TYPE_MAGICFIELD = 6;
/**
* Teleport.
*
* @version 0.1.0
* @since 0.1.0
*/
const ITEM_TYPE_TELEPORT = 7;
/**
* Can block characters from walking.
*/
const FLAG_BLOCK_SOLID = 1;
/**
* BLOCK_PROJECTILE flag(?).
*/
const FLAG_BLOCK_PROJECTILE = 2;
/**
* Can block searching for path.
*/
const FLAG_BLOCK_PATHFIND = 4;
/**
* Does item rises stack height on it's field.
*/
const FLAG_HAS_HEIGHT = 8;
/**
* Can be used by players.
*/
const FLAG_USEABLE = 16;
/**
* Can be picked up by player.
*/
const FLAG_PICKUPABLE = 32;
/**
* Can be moved by player.
*/
const FLAG_MOVEABLE = 64;
/**
* Can be grouped with another items.
*/
const FLAG_STACKABLE = 128;
/**
* Changes floor under it.
*/
const FLAG_FLOORCHANGEDOWN = 256;
/**
* Changes floor north from it's position.
*/
const FLAG_FLOORCHANGENORTH = 512;
/**
* Changes floor east from it's position.
*/
const FLAG_FLOORCHANGEEAST = 1024;
/**
* Changes floor south from it's position.
*/
const FLAG_FLOORCHANGESOUTH = 2048;
/**
* Changes floor west from it's position.
*/
const FLAG_FLOORCHANGEWEST = 4096;
/**
* Is always over other items in stack.
*/
const FLAG_ALWAYSONTOP = 8192;
/**
* Has readable sign.
*/
const FLAG_READABLE = 16384;
/**
* Can be rotated by player.
*/
const FLAG_ROTABLE = 32768;
/**
* Can be hang(?).
*/
const FLAG_HANGABLE = 65536;
/**
* Is oriented verticaly.
*/
const FLAG_VERTICAL = 131072;
/**
* Is oriented horizontaly.
*/
const FLAG_HORIZONTAL = 262144;
/**
* Doesn't decay.
*/
const FLAG_CANNOTDECAY = 524288;
/**
* Can be read from distance.
*/
const FLAG_ALLOWDISTREAD = 1048576;
/**
* Item type (server) ID.
*
* @var int
*/
private $id;
/**
* Item client mask ID.
*
* @var int
*/
private $clientId;
/**
* Item name.
*
* @var string
*/
private $name;
/**
* Attributes.
*
* @var array
*/
private $attributes;
/**
* Item group.
*
* @var int
*/
private $group = self::ITEM_GROUP_NONE;
/**
* Item type.
*
* @var int
*/
private $type = self::ITEM_TYPE_NONE;
/**
* Type flags.
*
* @var int
*/
private $flags;
/**
* Initializes new item type object.
*
* @param int $id Server ID.
*/
public function __construct($id)
{
$this->id = $id;
}
/**
* Magic PHP5 method.
*
* <p>
* Allows object importing from {@link http://www.php.net/manual/en/function.var-export.php var_export()}.
* </p>
*
* @version 0.1.3
* @param array $properties List of object properties.
*/
public static function __set_state($properties)
{
$object = new self($properties['id']);
unset($properties['id']);
// loads properties
foreach($properties as $name => $value)
{
$object->$name = $value;
}
return $object;
}
/**
* Returns item type server ID.
*
* @return int ID.
*/
public function getId()
{
return $this->id;
}
/**
* Returns item type client ID.
*
* @return int Cient ID.
*/
public function getClientId()
{
return $this->clientId;
}
/**
* Sets client side ID.
*
* @param int $clientId Client ID.
*/
public function setClientId($clientId)
{
$this->clientId = $clientId;
}
/**
* Returns item name.
*
* @return string Item type name.
*/
public function getName()
{
return $this->name;
}
/**
* Sets item type name.
*
* @param string $name Name.
*/
public function setName($name)
{
$this->name = $name;
}
/**
* Checks if this type has given attribute.
*
* @version 0.1.3
* @since 0.1.3
* @param string $attribyte Attribute name.
* @return bool Attribute set state.
*/
public function hasAttribute($name)
{
return isset($this->attributes[$name]);
}
/**
* Returns given attribute.
*
* @version 0.1.3
* @param string $attribyte Attribute name.
* @return string Attribute value.
* @throws OutOfBoundsException If not set.
*/
public function getAttribute($name)
{
if( isset($this->attributes[$name]) )
{
return $this->attributes[$name];
}
throw new OutOfBoundsException();
}
/**
* Sets given attribute.
*
* @param string $attribute Attribute name.
* @param string $value Attribute value.
*/
public function setAttribute($name, $value)
{
$this->attributes[$name] = $value;
}
/**
* Returns all attributes list.
*
* @return array List of attributes.
*/
public function getAttributesList()
{
return $this->attributes;
}
/**
* Returns group.
*
* @return int Item group.
*/
public function getGroup()
{
return $this->group;
}
/**
* Sets item group.
*
* @param int $group Group.
*/
public function setGroup($group)
{
$this->group = $group;
}
/**
* Returns item type.
*
* @return int Item type.
*/
public function getType()
{
return $this->type;
}
/**
* Sets item type.
*
* @param int $type Type.
*/
public function setType($type)
{
$this->type = $type;
}
/**
* Sets type flags.
*
* @param int $flags Flags.
*/
public function setFlags($flags)
{
$this->flags = $flags;
}
/**
* Checks if item is blocking.
*
* @return bool Is item blocking.
*/
public function isBlocking()
{
return ($this->flags & self::FLAG_BLOCK_SOLID) == self::FLAG_BLOCK_SOLID;
}
/**
* Checks if item has height.
*
* @return bool Has item height.
*/
public function hasHeight()
{
return ($this->flags & self::FLAG_HAS_HEIGHT) == self::FLAG_HAS_HEIGHT;
}
/**
* Checks if item is usable.
*
* @return bool Is item usable.
*/
public function isUsable()
{
return ($this->flags & self::FLAG_USEABLE) == self::FLAG_USEABLE;
}
/**
* Checks if item is pickupable.
*
* @return bool Is item pickuable.
*/
public function isPickupable()
{
return ($this->flags & self::FLAG_PICKUPABLE) == self::FLAG_PICKUPABLE;
}
/**
* Checks if item is movable.
*
* @return bool Is item movable.
*/
public function isMovable()
{
return ($this->flags & self::FLAG_MOVEABLE) == self::FLAG_MOVEABLE;
}
/**
* Checks if item is stackable.
*
* @return bool Is item stackable.
*/
public function isStackable()
{
return ($this->flags & self::FLAG_STACKABLE) == self::FLAG_STACKABLE;
}
/**
* Checks if item is always on top.
*
* @return bool Is item always on top.
*/
public function isAlwaysOnTop()
{
return ($this->flags & self::FLAG_ALWAYSONTOP) == self::FLAG_ALWAYSONTOP;
}
/**
* Checks if item is readable.
*
* @return bool Is item readable.
*/
public function isReadable()
{
return ($this->flags & self::FLAG_READABLE) == self::FLAG_READABLE;
}
/**
* Checks if item can be rotated.
*
* @return bool Is item can be rotated.
*/
public function isRotable()
{
return ($this->flags & self::FLAG_ROTABLE) == self::FLAG_ROTABLE;
}
/**
* Checks if item can be hanged.
*
* @return bool Is item can be hanged.
*/
public function isHangable()
{
return ($this->flags & self::FLAG_HANGABLE) == self::FLAG_HANGABLE;
}
/**
* Checks if item is vertical.
*
* @return bool Is item vertical.
*/
public function isVertical()
{
return ($this->flags & self::FLAG_VERTICAL) == self::FLAG_VERTICAL;
}
/**
* Checks if item is horizontal.
*
* @return bool Is item horizontal.
*/
public function isHorizontal()
{
return ($this->flags & self::FLAG_HORIZONTAL) == self::FLAG_HORIZONTAL;
}
/**
* Creates instance of this type.
*
* @return OTS_Item Item instance.
*/
public function createItem()
{
// container
if($this->group == self::ITEM_GROUP_CONTAINER)
{
return new OTS_Container($this->id);
}
// normal item
else
{
return new OTS_Item($this->id);
}
}
/**
* Magic PHP5 method.
*
* @version 0.1.0
* @since 0.1.0
* @param string $name Property name.
* @return mixed Property value.
* @throws OutOfBoundsException For non-supported properties.
*/
public function __get($name)
{
switch($name)
{
case 'id':
return $this->getId();
case 'clientId':
return $this->getClientId();
case 'name':
return $this->getName();
case 'group':
return $this->getGroup();
case 'type':
return $this->getType();
case 'attributesList':
return $this->getAttributesList();
case 'blocking':
return $this->isBlocking();
case 'hasHeight':
return $this->hasHeight();
case 'usable':
return $this->isUsable();
case 'pickupable':
return $this->isPickupable();
case 'movable':
return $this->isMovable();
case 'stackable':
return $this->isStackable();
case 'alwaysOnTop':
return $this->isAlwaysOnTop();
case 'readable':
return $this->isReadable();
case 'rotable':
return $this->isRotable();
case 'hangable':
return $this->isHangable();
case 'vertical':
return $this->isVertical();
case 'horizontal':
return $this->isHorizontal();
default:
throw new OutOfBoundsException();
}
}
/**
* Magic PHP5 method.
*
* @version 0.1.0
* @since 0.1.0
* @param string $name Property name.
* @param mixed $value Property value.
* @throws OutOfBoundsException For non-supported properties.
*/
public function __set($name, $value)
{
switch($name)
{
case 'flags':
$this->setFlags($value);
break;
case 'clientId':
$this->setClientId($value);
break;
case 'name':
$this->setName($value);
break;
case 'group':
$this->setGroup($value);
break;
case 'type':
$this->setType($value);
break;
default:
throw new OutOfBoundsException();
}
}
/**
* Returns string representation of object.
*
* <p>
* If any display driver is currently loaded then it uses it's method. Otherwise just returns item ID.
* </p>
*
* @version 0.1.3
* @since 0.1.3
* @return string String representation of object.
*/
public function __toString()
{
$ots = POT::getInstance();
// checks if display driver is loaded
if( $ots->isDataDisplayDriverLoaded() )
{
return $ots->getDataDisplayDriver()->displayItemType($this);
}
return $this->getId();
}
}
/**#@-*/
?>

View File

@@ -0,0 +1,680 @@
<?php
/**#@+
* @version 0.0.8
* @since 0.0.8
*/
/**
* Code in this file bases on oryginal OTServ items loading C++ code (itemloader.h, items.cpp, items.h).
*
* @package POT
* @version 0.1.3
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 - 2008 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/
/**
* Items list loader.
*
* @package POT
* @version 0.1.3
* @property-read int $otbVersion OTB file version.
* @property-read int $clientVersion Dedicated client version.
* @property-read int $buildVersion File build version.
* @tutorial POT/data_directory.pkg#items
*/
class OTS_ItemsList extends OTS_FileLoader implements IteratorAggregate, Countable, ArrayAccess
{
/**
* Root file attribute.
*/
const ROOT_ATTR_VERSION = 1;
/**
* Tibia client 7.5 version.
*/
const CLIENT_VERSION_750 = 1;
/**
* Tibia client 7.55 version.
*/
const CLIENT_VERSION_755 = 2;
/**
* Tibia client 7.6 version.
*/
const CLIENT_VERSION_760 = 3;
/**
* Tibia client 7.7 version.
*/
const CLIENT_VERSION_770 = 3;
/**
* Tibia client 7.8 version.
*/
const CLIENT_VERSION_780 = 4;
/**
* Tibia client 7.9 version.
*/
const CLIENT_VERSION_790 = 5;
/**
* Tibia client 7.92 version.
*/
const CLIENT_VERSION_792 = 6;
/**
* Tibia client 8.0 version.
*/
const CLIENT_VERSION_800 = 7;
/**
* Server ID.
*/
const ITEM_ATTR_SERVERID = 16;
/**
* Client ID.
*/
const ITEM_ATTR_CLIENTID = 17;
/**
* Speed.
*/
const ITEM_ATTR_SPEED = 20;
/**
* Light.
*/
const ITEM_ATTR_LIGHT2 = 42;
/**
* Always-on-top order.
*/
const ITEM_ATTR_TOPORDER = 43;
/**
* Temple positions.
*
* @var array
*/
private $items = array();
/**
* OTB version.
*
* @var int
*/
private $otbVersion;
/**
* Client version.
*
* @var int
*/
private $clientVersion;
/**
* Build version.
*
* @var int
*/
private $buildVersion;
/**
* Magic PHP5 method.
*
* <p>
* Allows object unserialisation.
* </p>
*/
public function __wakeup()
{
// loads map info from recovered root node
$this->parse();
}
/**
* Loads items.xml and items.otb files.
*
* <p>
* This method loads both items.xml and items.otb files. Both of them has to be in given directory.
* </p>
*
* @version 0.1.3
* @param string $path Path to data/items directory.
* @throws E_OTS_FileLoaderError When error occurs during file operation.
* @throws DOMException On DOM operation error.
*/
public function loadItems($path)
{
$empty = false;
// loads items.xml cache
if( isset($this->cache) && $this->cache instanceof IOTS_ItemsCache)
{
$this->items = $this->cache->readItems( md5_file($path . '/items.xml') );
}
// checks if cache is loaded
if( empty($this->items) )
{
// marks list to be saved in new cache
$empty = true;
// lodas XML file
$xml = new DOMDocument();
$xml->load($path . '/items.xml');
// reads items info
foreach( $xml->documentElement->getElementsByTagName('item') as $tag)
{
// composes basic item info
$item = new OTS_ItemType( $tag->getAttribute('id') );
$item->setName( $tag->getAttribute('name') );
// reads attributes
foreach( $tag->getElementsByTagName('attribute') as $attribute)
{
$item->setAttribute( $attribute->getAttribute('key'), $attribute->getAttribute('value') );
}
$this->items[ $item->getId() ] = $item;
}
}
// loads items.otb
$this->loadFile($path . '/items.otb');
// parses loaded file
$this->parse();
// saves cache
if($empty && isset($this->cache) && $this->cache instanceof IOTS_ItemsCache)
{
$this->cache->writeItems( md5_file($path . '/items.xml'), $this->items);
}
}
/**
* Parses loaded file.
*
* @version 0.1.0
* @throws E_OTS_FileLoaderError If file has invalid format.
*/
private function parse()
{
// root node header
$this->root->skip(4);
// root attribute
if( $this->root->getChar() == self::ROOT_ATTR_VERSION)
{
// checks if data lengths if same as version record which is supposed to be stored here
if( $this->root->getShort() != 140)
{
throw E_OTS_FileLoaderError(E_OTS_FileLoaderError::ERROR_INVALID_FORMAT);
}
// version record
$this->otbVersion = $this->root->getLong();
$this->clientVersion = $this->root->getLong();
$this->buildVersion = $this->root->getLong();
}
// reads root's first child
$node = $this->root->getChild();
// reads all item types
while($node)
{
// resets info
$id = null;
$clientId = null;
$speed = null;
$lightLevel = null;
$lightColor = null;
$topOrder = null;
// reads flags
$flags = $node->getLong();
// reads node attributes
while( $node->isValid() )
{
$attribute = $node->getChar();
$length = $node->getShort();
switch($attribute)
{
// server-side ID
case self::ITEM_ATTR_SERVERID:
// checks length
if($length != 2)
{
throw E_OTS_FileLoaderError(E_OTS_FileLoaderError::ERROR_INVALID_FORMAT);
}
$id = $node->getShort();
break;
// client-side ID
case self::ITEM_ATTR_CLIENTID:
// checks length
if($length != 2)
{
throw E_OTS_FileLoaderError(E_OTS_FileLoaderError::ERROR_INVALID_FORMAT);
}
$clientId = $node->getShort();
break;
// speed
case self::ITEM_ATTR_SPEED:
// checks length
if($length != 2)
{
throw E_OTS_FileLoaderError(E_OTS_FileLoaderError::ERROR_INVALID_FORMAT);
}
$speed = $node->getShort();
break;
// server-side ID
case self::ITEM_ATTR_LIGHT2:
// checks length
if($length != 4)
{
throw E_OTS_FileLoaderError(E_OTS_FileLoaderError::ERROR_INVALID_FORMAT);
}
$lightLevel = $node->getShort();
$lightColor = $node->getShort();
break;
// server-side ID
case self::ITEM_ATTR_TOPORDER:
// checks length
if($length != 1)
{
throw E_OTS_FileLoaderError(E_OTS_FileLoaderError::ERROR_INVALID_FORMAT);
}
$topOrder = $node->getChar();
break;
// skips unknown attributes
default:
$node->skip($length);
}
}
// checks if type exist
if( isset($this->items[$id]) )
{
$type = $this->items[$id];
$type->setGroup( $node->getType() );
$type->setFlags($flags);
// sets OTB attributes
if( isset($clientId) )
{
$type->setClientId($clientId);
}
if( isset($speed) )
{
$type->setAttribute('speed', $speed);
}
if( isset($lightLevel) )
{
$type->setAttribute('lightLevel', $lightLevel);
}
if( isset($lightColor) )
{
$type->setAttribute('lightColor', $lightColor);
}
if( isset($topOrder) )
{
$type->setAttribute('topOrder', $topOrder);
}
switch( $node->getType() )
{
// container
case OTS_ItemType::ITEM_GROUP_CONTAINER:
$type->setType(OTS_ItemType::ITEM_TYPE_CONTAINER);
break;
// door
case OTS_ItemType::ITEM_GROUP_DOOR:
$type->setType(OTS_ItemType::ITEM_TYPE_DOOR);
break;
// magic field
case OTS_ItemType::ITEM_GROUP_MAGICFIELD:
$type->setType(OTS_ItemType::ITEM_TYPE_MAGICFIELD);
break;
// teleport field
case OTS_ItemType::ITEM_GROUP_TELEPORT:
$type->setType(OTS_ItemType::ITEM_TYPE_TELEPORT);
break;
// nothing special for this groups but we have to separate from default section
case OTS_ItemType::ITEM_GROUP_NONE:
case OTS_ItemType::ITEM_GROUP_GROUND:
case OTS_ItemType::ITEM_GROUP_RUNE:
case OTS_ItemType::ITEM_GROUP_SPLASH:
case OTS_ItemType::ITEM_GROUP_FLUID:
case OTS_ItemType::ITEM_GROUP_DEPRECATED:
break;
// unknown type
default:
throw new E_OTS_FileLoaderError(E_OTS_FileLoaderError::ERROR_INVALID_FORMAT);
}
}
$node = $node->getNext();
}
}
/**
* Returns OTB file version.
*
* @return int OTB format version.
*/
public function getOTBVersion()
{
return $this->otbVersion;
}
/**
* Returns client version.
*
* @return int Client version.
*/
public function getClientVersion()
{
return $this->clientVersion;
}
/**
* Returns build version.
*
* @return int Build version.
*/
public function getBuildVersion()
{
return $this->buildVersion;
}
/**
* Checks if given item type exists on list.
*
* @version 0.1.3
* @since 0.1.3
* @param string $name Name.
* @return bool If item type is set then true.
*/
public function hasItemType($name)
{
foreach($this->items as $id => $type)
{
if( $type->getName() == $name)
{
// found it
return true;
}
}
return false;
}
/**
* Returns given item type.
*
* @version 0.1.3
* @param int $id Item type (server) ID.
* @return OTS_ItemType Returns item type of given ID.
* @throws OutOfBoundsException If not exists.
*/
public function getItemType($id)
{
if( isset($this->items[$id]) )
{
return $this->items[$id];
}
throw new OutOfBoundsException();
}
/**
* Checks if given type ID exists on list.
*
* @version 0.1.3
* @since 0.1.3
* @param int $id ID.
* @return bool If item type is set then true.
*/
public function hasItemTypeId($id)
{
return isset($this->items[$id]);
}
/**
* Finds item type by it's name.
*
* <p>
* Note: If there are more then one items with same name this function will return first found server ID. It doesn't also mean that it will be the lowest ID - item types are ordered in order that they were loaded from items.xml file.
* </p>
*
* @version 0.1.3
* @param string $name Item type name.
* @return int Returns item type (server) ID.
* @throws OutOfBoundsException If not found.
*/
public function getItemTypeId($name)
{
foreach($this->items as $id => $type)
{
if( $type->getName() == $name)
{
// found it
return $id;
}
}
// not found
throw new OutOfBoundsException();
}
/**
* @return array List of item types.
* @deprecated 0.1.0 Use this class object as array for iterations, counting and methods for field fetching.
*/
public function getItemTypesList()
{
return $this->items;
}
/**
* Returns amount of items loaded.
*
* @return int Count of types.
*/
public function count()
{
return count($this->items);
}
/**
* @return string Item name.
* @deprecated 0.1.0 Use getIterator().
*/
public function current()
{
return current($this->items);
}
/**
* @deprecated 0.1.0 Use getIterator().
*/
public function next()
{
next($this->items);
}
/**
* @return int Current position key.
* @deprecated 0.1.0 Use getIterator().
*/
public function key()
{
return key($this->items);
}
/**
* @return bool If iterator has anything more.
* @deprecated 0.1.0 Use getIterator().
*/
public function valid()
{
return key($this->items) !== null;
}
/**
* @deprecated 0.1.0 Use getIterator().
*/
public function rewind()
{
reset($this->items);
}
/**
* Returns iterator handle for loops.
*
* @version 0.1.0
* @since 0.1.0
* @return ArrayIterator Items list iterator.
*/
public function getIterator()
{
return new ArrayIterator($this->items);
}
/**
* Checks if given element exists.
*
* @version 0.1.0
* @since 0.1.0
* @param string|int $offset Array key.
* @return bool True if it's set.
*/
public function offsetExists($offset)
{
// integer key
if( is_int($offset) )
{
return isset($this->items[$offset]);
}
// item type name
return $this->hasItemType($offset);
}
/**
* Returns item from given position.
*
* @version 0.1.3
* @since 0.1.0
* @param string|int $offset Array key.
* @return OTS_ItemType|int If key is an integer (type-sensitive!) then returns item type instance. If it's a string then return associated ID found by type name.
*/
public function offsetGet($offset)
{
// integer key
if( is_int($offset) )
{
return $this->getItemType($offset);
}
// house name
return $this->getItemTypeId($offset);
}
/**
* This method is implemented for ArrayAccess interface. In fact you can't write/append to items list. Any call to this method will cause {@link E_OTS_ReadOnly E_OTS_ReadOnly} raise.
*
* @version 0.1.0
* @since 0.1.0
* @param string|int $offset Array key.
* @param mixed $value Field value.
* @throws E_OTS_ReadOnly Always - this class is read-only.
*/
public function offsetSet($offset, $value)
{
throw new E_OTS_ReadOnly();
}
/**
* This method is implemented for ArrayAccess interface. In fact you can't write/append to items list. Any call to this method will cause {@link E_OTS_ReadOnly E_OTS_ReadOnly} raise.
*
* @version 0.1.0
* @since 0.1.0
* @param string|int $offset Array key.
* @throws E_OTS_ReadOnly Always - this class is read-only.
*/
public function offsetUnset($offset)
{
throw new E_OTS_ReadOnly();
}
/**
* Magic PHP5 method.
*
* @version 0.1.0
* @since 0.1.0
* @param string $name Property name.
* @return mixed Property value.
* @throws OutOfBoundsException For non-supported properties.
*/
public function __get($name)
{
switch($name)
{
case 'otbVersion':
case 'clientVersion':
case 'buildVersion':
return $this->$name;
default:
throw new OutOfBoundsException();
}
}
/**
* Returns string representation of object.
*
* <p>
* If any display driver is currently loaded then it uses it's method.
* </p>
*
* @version 0.1.3
* @since 0.1.3
* @return string String representation of object.
*/
public function __toString()
{
$ots = POT::getInstance();
// checks if display driver is loaded
if( $ots->isDataDisplayDriverLoaded() )
{
return $ots->getDataDisplayDriver()->displayItemsList($this);
}
return (string) $this->count();
}
}
/**#@-*/
?>

View File

@@ -0,0 +1,134 @@
<?php
/**#@+
* @version 0.0.6
* @since 0.0.6
*/
/**
* Code in this file bases on oryginal OTServ OTBM format loading C++ code (iomapotbm.h, iomapotbm.cpp).
*
* @package POT
* @version 0.1.0
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/
/**
* Map position point.
*
* @package POT
* @version 0.1.0
* @property-read int $x X coord.
* @property-read int $y Y coord.
* @property-read int $z Z coord.
*/
class OTS_MapCoords
{
/**
* X.
*
* @var int
*/
private $x;
/**
* Y.
*
* @var int
*/
private $y;
/**
* Z.
*
* @var int
*/
private $z;
/**
* Sets coords for point.
*
* @param int $x X.
* @param int $y Y.
* @param int $z Z.
*/
public function __construct($x, $y, $z)
{
$this->x = $x;
$this->y = $y;
$this->z = $z;
}
/**
* Magic PHP5 method.
*
* <p>
* Allows object importing from {@link http://www.php.net/manual/en/function.var-export.php var_export()}.
* </p>
*
* @param array $properties List of object properties.
*/
public static function __set_state($properties)
{
return new self($properties['x'], $properties['y'], $properties['z']);
}
/**
* Returns X.
*
* @return int X.
*/
public function getX()
{
return $this->x;
}
/**
* Returns Y.
*
* @return int Y.
*/
public function getY()
{
return $this->y;
}
/**
* Returns Z.
*
* @return int Z.
*/
public function getZ()
{
return $this->z;
}
/**
* Magic PHP5 method.
*
* @version 0.1.0
* @since 0.1.0
* @param string $name Property name.
* @return mixed Property value.
* @throws OutOfBoundsException For non-supported properties.
*/
public function __get($name)
{
switch($name)
{
case 'x':
case 'y':
case 'z':
return $this->$name;
default:
throw new OutOfBoundsException();
}
}
}
/**#@-*/
?>

View File

@@ -0,0 +1,488 @@
<?php
/**#@+
* @version 0.0.6
* @since 0.0.6
*/
/**
* @package POT
* @version 0.1.3
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 - 2008 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/
/**
* Wrapper for monsters files DOMDocument.
*
* <p>
* Note: as this class extends {@link http://www.php.net/manual/en/ref.dom.php DOMDocument class} and contains exacly file XML tree you can work on it as on normal DOM tree.
* </p>
*
* @package POT
* @version 0.1.3
* @property-read string $name Monster name.
* @property-read string $race Monster race.
* @property-read int $experience Experience for killing monster.
* @property-read int $speed Monster speed.
* @property-read int|bool $manaCost Mana required (false if not possible).
* @property-read int $health Hit points.
* @property-read array $flags Flags.
* @property-read array $voices List of sounds.
* @property-read array $items List of possible loot.
* @property-read array $immunities List of immunities.
* @property-read int $defense Defense rate.
* @property-read int $armor Armor rate.
* @property-read array $defenses List of defenses.
* @property-read array $attacks List of attacks.
*/
class OTS_Monster extends DOMDocument
{
/**
* Returns monster name.
*
* @return string Name.
* @throws DOMException On DOM operation error.
*/
public function getName()
{
return $this->documentElement->getAttribute('name');
}
/**
* Returns monster race.
*
* @return string Race.
* @throws DOMException On DOM operation error.
*/
public function getRace()
{
return $this->documentElement->getAttribute('race');
}
/**
* Returns amount of experience for killing this monster.
*
* @return int Experience points.
* @throws DOMException On DOM operation error.
*/
public function getExperience()
{
return (int) $this->documentElement->getAttribute('experience');
}
/**
* Returns monster speed.
*
* @return int Speed.
* @throws DOMException On DOM operation error.
*/
public function getSpeed()
{
return (int) $this->documentElement->getAttribute('speed');
}
/**
* Returns amount of mana required to summon this monster.
*
* @return int|bool Mana required (false if not possible).
* @throws DOMException On DOM operation error.
*/
public function getManaCost()
{
// check if it is possible to summon this monster
if( $this->documentElement->hasAttribute('manacost') )
{
return (int) $this->documentElement->getAttribute('manacost');
}
else
{
return false;
}
}
/**
* Returns monster HP.
*
* @return int Hit points.
* @throws DOMException On DOM operation error.
*/
public function getHealth()
{
return (int) $this->documentElement->getElementsByTagName('health')->item(0)->getAttribute('max');
}
/**
* Returns all monster flags (in format flagname => value).
*
* @return array Flags.
* @throws DOMException On DOM operation error.
*/
public function getFlags()
{
$flags = array();
// read all flags
foreach( $this->documentElement->getElementsByTagName('flags')->item(0)->getElementsByTagName('flag') as $flag)
{
$flag = $flag->attributes->item(0);
$flags[$flag->nodeName] = (int) $flag->nodeValue;
}
return $flags;
}
/**
* Returns specified flag value.
*
* @param string $flag Flag.
* @return int|bool Flag value (false if not set).
* @throws DOMException On DOM operation error.
*/
public function getFlag($flag)
{
// searches for flag
foreach( $this->documentElement->getElementsByTagName('flags')->item(0)->getElementsByTagName('flag') as $flag)
{
// found
if( $flag->hasAttribute($flag) )
{
return (int) $flag->getAttribute($flag);
}
}
// not found
return false;
}
/**
* Returns voices that monster can sound.
*
* @return array List of voices.
* @throws DOMException On DOM operation error.
*/
public function getVoices()
{
$voices = array();
$element = $this->documentElement->getElementsByTagName('voices')->item(0);
// checks if it has any voices
if( isset($element) )
{
// loads all voices
foreach( $element->getElementsByTagName('voice') as $voice)
{
$voices[] = $voice->getAttribute('sentence');
}
}
return $voices;
}
/**
* @return array List of item IDs.
* @deprecated 0.1.0 Use getItems().
*/
public function getLoot()
{
$loot = array();
$element = $this->documentElement->getElementsByTagName('loot')->item(0);
// checks if it has any loot
if( isset($element) )
{
// adds all items
foreach( $element->getElementsByTagName('item') as $item)
{
$id = $item->getAttribute('id');
// avoid redundancy
if( !in_array($id, $loot) )
{
$loot[] = $id;
}
}
}
return $loot;
}
/**
* Returns all possible loot.
*
* <p>
* In order to use this method you have to have global items list loaded.
* </p>
*
* @version 0.1.0
* @since 0.1.0
* @return array List of item types.
* @throws E_OTS_NotLoaded When there is no items list available in global POT instance.
* @throws DOMException On DOM operation error.
*/
public function getItems()
{
$loot = array();
$keys = array();
$items = POT::getInstance()->getItemsList();
$element = $this->documentElement->getElementsByTagName('loot')->item(0);
// checks if it has any loot
if( isset($element) )
{
// adds all items
foreach( $element->getElementsByTagName('item') as $item)
{
$id = $item->getAttribute('id');
// avoid redundancy
if( !in_array($id, $keys) )
{
$keys[] = $id;
$loot[] = $items->getItemType($id);
}
}
}
return $loot;
}
/**
* Returns all monster immunities.
*
* @return array Immunities.
* @throws DOMException On DOM operation error.
*/
public function getImmunities()
{
$immunities = array();
$element = $this->documentElement->getElementsByTagName('immunities')->item(0);
// checks if it has any immunities
if( isset($element) )
{
// read all immunities
foreach( $element->getElementsByTagName('immunity') as $immunity)
{
$immunity = $immunity->attributes->item(0);
// checks if immunity is set
if($immunity->nodeValue > 0)
{
$immunities[] = $immunity->nodeName;
}
}
}
return $immunities;
}
/**
* Checks if monster has given immunity.
*
* @param string $name Immunity to check.
* @return bool Immunity state.
* @throws DOMException On DOM operation error.
*/
public function hasImmunity($name)
{
$element = $this->documentElement->getElementsByTagName('immunities')->item(0);
// if doesn't have any immunities obviously doesn't have this one too
if( isset($element) )
{
// read all immunities
foreach( $element->getElementsByTagName('immunity') as $immunity)
{
// checks if this is what we are searching for
if( $immunity->hasAttribute($name) )
{
return $immunity->getAttribute($name) > 0;
}
}
}
return false;
}
/**
* Returns monster defense rate.
*
* @return int Defense rate.
* @throws DOMException On DOM operation error.
*/
public function getDefense()
{
$element = $this->documentElement->getElementsByTagName('defenses')->item(0);
// checks if defenses element is set
if( isset($element) )
{
return (int) $element->getAttribute('defense');
}
return 0;
}
/**
* Returns monster armor.
*
* @return int Armor rate.
* @throws DOMException On DOM operation error.
*/
public function getArmor()
{
$element = $this->documentElement->getElementsByTagName('defenses')->item(0);
// checks if defenses element is set
if( isset($element) )
{
return (int) $element->getAttribute('armor');
}
return 0;
}
/**
* Returns list of special defenses.
*
* @return array List of defense effects.
* @throws DOMException On DOM operation error.
*/
public function getDefenses()
{
$defenses = array();
$element = $this->documentElement->getElementsByTagName('defenses')->item(0);
// checks if it has any defenses
if( isset($element) )
{
foreach( $element->getElementsByTagName('defense') as $defense)
{
$defenses[] = $defense->getAttribute('name');
}
}
return $defenses;
}
/**
* Returns list of monster attacks.
*
* @return array List of attafck effects.
* @throws DOMException On DOM operation error.
*/
public function getAttacks()
{
$attacks = array();
$element = $this->documentElement->getElementsByTagName('attacks')->item(0);
// checks if it has any defenses
if( isset($element) )
{
foreach( $element->getElementsByTagName('attack') as $attack)
{
$attacks[] = $attack->getAttribute('name');
}
}
return $attacks;
}
/**
* Magic PHP5 method.
*
* @version 0.1.0
* @since 0.1.0
* @param string $name Property name.
* @return mixed Property value.
* @throws OutOfBoundsException For non-supported properties.
* @throws DOMException On DOM operation error.
*/
public function __get($name)
{
switch($name)
{
case 'name':
return $this->getName();
case 'race':
return $this->getRace();
case 'experience':
return $this->getExperience();
case 'speed':
return $this->getSpeed();
case 'manaCost':
return $this->getManaCost();
case 'health':
return $this->getHealth();
case 'flags':
return $this->getFlags();
case 'voices':
return $this->getVoices();
case 'items':
return $this->getItems();
case 'immunities':
return $this->getImmunities();
case 'defense':
return $this->getDefense();
case 'armor':
return $this->getArmor();
case 'defenses':
return $this->getDefenses();
case 'attacks':
return $this->getAttacks();
default:
throw new OutOfBoundsException();
}
}
/**
* Returns string representation of XML.
*
* <p>
* If any display driver is currently loaded then it uses it's method. Otherwise just returns monster XML content.
* </p>
*
* @version 0.1.3
* @since 0.1.0
* @return string String representation of object.
*/
public function __toString()
{
$ots = POT::getInstance();
// checks if display driver is loaded
if( $ots->isDataDisplayDriverLoaded() )
{
return $ots->getDataDisplayDriver()->displayMonster($this);
}
return $this->saveXML();
}
}
/**#@-*/
?>

View File

@@ -0,0 +1,263 @@
<?php
/**#@+
* @version 0.1.0
* @since 0.1.0
*/
/**
* @package POT
* @version 0.1.3
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 - 2008 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/
/**
* Wrapper for monsters list.
*
* @package POT
* @version 0.1.3
* @tutorial POT/data_directory.pkg#monsters
*/
class OTS_MonstersList implements Iterator, Countable, ArrayAccess
{
/**
* Monsters directory.
*
* @var string
*/
private $monstersPath;
/**
* List of loaded monsters.
*
* @var array
*/
private $monsters = array();
/**
* Loads monsters mapping file.
*
* <p>
* Note: You pass directory path, not monsters.xml file name itself.
* </p>
*
* @param string $path Monsters directory.
* @throws DOMException On DOM operation error.
*/
public function __construct($path)
{
$this->monstersPath = $path;
// makes sure it has directory separator at the end
$last = substr($this->monstersPath, -1);
if($last != '/' && $last != '\\')
{
$this->monstersPath .= '/';
}
// loads monsters mapping file
$monsters = new DOMDocument();
$monsters->load($this->monstersPath . 'monsters.xml');
foreach( $monsters->getElementsByTagName('monster') as $monster)
{
$this->monsters[ $monster->getAttribute('name') ] = $monster->getAttribute('file');
//echo $this->monsters[ $monster->getAttribute('name')];
}
}
/**
* Magic PHP5 method.
*
* Allows object importing from {@link http://www.php.net/manual/en/function.var-export.php var_export()}.
*
* @param array $properties List of object properties.
*/
public function __set_state($properties)
{
$object = new self();
// loads properties
foreach($properties as $name => $value)
{
$object->$name = $value;
}
return $object;
}
/**
* Checks if given monster ID exists on list.
*
* @version 0.1.3
* @since 0.1.3
* @param string $name Monster name.
* @return bool If monster is set then true.
*/
public function hasMonster($name)
{
return isset($this->monsters[$name]);
}
/**
* Returns loaded data of given monster.
*
* @version 0.1.3
* @param string $name Monster name.
* @return OTS_Monster Monster data.
* @throws OutOfBoundsException If not exists.
* @throws DOMException On DOM operation error.
*/
public function getMonster($name)
{
// checks if monster exists
if( isset($this->monsters[$name]) )
{
// loads file
$monster = new OTS_Monster();
$monster->load($this->monstersPath . $this->monsters[$name]);
return $monster;
}
throw new OutOfBoundsException();
}
/**
* Returns amount of monsters loaded.
*
* @return int Count of monsters.
*/
public function count()
{
return count($this->monsters);
}
/**
* Returns monster at current position in iterator.
*
* @return OTS_Monster Monster.
* @throws DOMException On DOM operation error.
*/
public function current()
{
return $this->getMonster( key($this->monsters) );
}
public function currentFile()
{
return $this->monsters[key($this->monsters)];
}
/**
* Moves to next iterator monster.
*/
public function next()
{
next($this->monsters);
}
/**
* Returns name of current position.
*
* @return string Current position key.
*/
public function key()
{
return key($this->monsters);
}
/**
* Checks if there is anything more in interator.
*
* @return bool If iterator has anything more.
*/
public function valid()
{
return key($this->monsters) !== null;
}
/**
* Resets iterator index.
*/
public function rewind()
{
reset($this->monsters);
}
/**
* Checks if given element exists.
*
* @param string $offset Array key.
* @return bool True if it's set.
*/
public function offsetExists($offset)
{
return isset($this->monsters[$offset]);
}
/**
* Returns item from given position.
*
* @version 0.1.3
* @param string $offset Array key.
* @return OTS_Monster Monster instance.
* @throws DOMException On DOM operation error.
*/
public function offsetGet($offset)
{
return $this->getMonster($offset);
}
/**
* This method is implemented for ArrayAccess interface. In fact you can't write/append to monsters list. Any call to this method will cause {@link E_OTS_ReadOnly E_OTS_ReadOnly} raise.
*
* @param string|int $offset Array key.
* @param mixed $value Field value.
* @throws E_OTS_ReadOnly Always - this class is read-only.
*/
public function offsetSet($offset, $value)
{
throw new E_OTS_ReadOnly();
}
/**
* This method is implemented for ArrayAccess interface. In fact you can't write/append to monsters list. Any call to this method will cause {@link E_OTS_ReadOnly E_OTS_ReadOnly} raise.
*
* @param string|int $offset Array key.
* @throws E_OTS_ReadOnly Always - this class is read-only.
*/
public function offsetUnset($offset)
{
throw new E_OTS_ReadOnly();
}
/**
* Returns string representation of object.
*
* <p>
* If any display driver is currently loaded then it uses it's method.
* </p>
*
* @version 0.1.3
* @since 0.1.3
* @return string String representation of object.
*/
public function __toString()
{
$ots = POT::getInstance();
// checks if display driver is loaded
if( $ots->isDataDisplayDriverLoaded() )
{
return $ots->getDataDisplayDriver()->displayMonstersList($this);
}
return (string) $this->count();
}
}
/**#@-*/
?>

View File

@@ -0,0 +1,842 @@
<?php
/**#@+
* @version 0.0.6
* @since 0.0.6
*/
/**
* Code in this file bases on oryginal OTServ OTBM format loading C++ code (iomapotbm.h, iomapotbm.cpp).
*
* @package POT
* @version 0.1.3
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 - 2008 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
* @todo future: Complete OTBM support: link tiles with items and spawns.
* @todo future: Spawns support.
* @todo future: New map format support.
*/
/**
* OTBM format reader.
*
* <p>
* POT OTBM file parser is less strict then oryginal OTServ one. For instance it will read waypoints from version 1 OTBM file even that there were no waypoints in that format.
* </p>
*
* @package POT
* @version 0.1.6
* @property-read OTS_HousesList $housesList Houses list loaded from associated houses file.
* @property-read int $width Map width.
* @property-read int $height Map height.
* @property-read string $description Map description.
* @property-read array $waypoints List of tracks on map.
* @tutorial POT/data_directory.pkg#towns
* @example examples/otbm.php otbm.php
*/
class OTS_OTBMFile extends OTS_FileLoader implements IteratorAggregate, Countable, ArrayAccess
{
/**
* Description attribute.
*/
const OTBM_ATTR_DESCRIPTION = 1;
/**
* External file.
*/
const OTBM_ATTR_EXT_FILE = 2;
/**
* Tile flags.
*/
const OTBM_ATTR_TILE_FLAGS = 3;
/**
* Action ID.
*/
const OTBM_ATTR_ACTION_ID = 4;
/**
* Unique ID.
*/
const OTBM_ATTR_UNIQUE_ID = 5;
/**
* Text.
*/
const OTBM_ATTR_TEXT = 6;
/**
* Description.
*/
const OTBM_ATTR_DESC = 7;
/**
* Teleport destination.
*/
const OTBM_ATTR_TELE_DEST = 8;
/**
* Item.
*/
const OTBM_ATTR_ITEM = 9;
/**
* Depot ID.
*/
const OTBM_ATTR_DEPOT_ID = 10;
/**
* External spawns file.
*/
const OTBM_ATTR_EXT_SPAWN_FILE = 11;
/**
* Rune changes amount.
*/
const OTBM_ATTR_RUNE_CHARGES = 12;
/**
* External houses file.
*/
const OTBM_ATTR_EXT_HOUSE_FILE = 13;
/**
* ID of doors.
*/
const OTBM_ATTR_HOUSEDOORID = 14;
/**
* Amount.
*
* @version 0.1.6
* @since 0.1.6
*/
const OTBM_ATTR_COUNT = 15;
/**
* Time interval.
*
* @version 0.1.6
* @since 0.1.6
*/
const OTBM_ATTR_DURATION = 16;
/**
* Metamorphic stage.
*
* @version 0.1.6
* @since 0.1.6
*/
const OTBM_ATTR_DECAYING_STATE = 17;
/**
* Date of being written.
*
* @version 0.1.6
* @since 0.1.6
*/
const OTBM_ATTR_WRITTENDATE = 18;
/**
* Sign author.
*
* @version 0.1.6
* @since 0.1.6
*/
const OTBM_ATTR_WRITTENBY = 19;
/**
* Sleeping player ID.
*
* @version 0.1.6
* @since 0.1.6
*/
const OTBM_ATTR_SLEEPERGUID = 20;
/**
* Time of sleep started.
*
* @version 0.1.6
* @since 0.1.6
*/
const OTBM_ATTR_SLEEPSTART = 21;
/**
* Number of charges.
*
* @version 0.1.6
* @since 0.1.6
*/
const OTBM_ATTR_CHARGES = 22;
/**
* Root node.
*/
const OTBM_NODE_ROOTV1 = 1;
/**
* Map data container.
*/
const OTBM_NODE_MAP_DATA = 2;
/**
* Item definition.
*/
const OTBM_NODE_ITEM_DEF = 3;
/**
* Map tiles fragment.
*/
const OTBM_NODE_TILE_AREA = 4;
/**
* Single tile.
*/
const OTBM_NODE_TILE = 5;
/**
* Item.
*/
const OTBM_NODE_ITEM = 6;
/**
* Tile.
*/
const OTBM_NODE_TILE_SQUARE = 7;
/**
* Tile reference.
*/
const OTBM_NODE_TILE_REF = 8;
/**
* Spawns container.
*/
const OTBM_NODE_SPAWNS = 9;
/**
* Spawn.
*/
const OTBM_NODE_SPAWN_AREA = 10;
/**
* Monster.
*/
const OTBM_NODE_MONSTER = 11;
/**
* Towns container.
*/
const OTBM_NODE_TOWNS = 12;
/**
* Town.
*/
const OTBM_NODE_TOWN = 13;
/**
* Tile of house.
*/
const OTBM_NODE_HOUSETILE = 14;
/**
* Waypoints list.
*
* @version 0.1.6
* @since 0.1.6
*/
const OTBM_NODE_WAYPOINTS = 15;
/**
* Waypoint.
*
* @version 0.1.6
* @since 0.1.6
*/
const OTBM_NODE_WAYPOINT = 16;
/**
* Map width.
*
* @var int
*/
private $width;
/**
* Map height.
*
* @var int
*/
private $height;
/**
* Map description.
*
* @var string
*/
private $description = '';
/**
* List of towns.
*
* @var array
*/
private $towns = array();
/**
* Temple positions.
*
* @var array
*/
private $temples = array();
/**
* Directory path.
*
* @var string
*/
private $directory;
/**
* External houses file.
*
* @var OTS_HousesList
*/
private $housesList;
/**
* List of map tracks.
*
* @var array
* @version 0.1.6
* @since 0.1.6
*/
protected $waypoints = array();
/**
* Magic PHP5 method.
*
* <p>
* Allows object unserialisation.
* </p>
*
* @throws E_OTS_FileLoaderError When error occurs during file operation.
*/
public function __wakeup()
{
// loads map info from recovered root node
$this->parse();
}
/**
* Loads OTBM file content.
*
* @version 0.1.0
* @param string $file Filename.
* @throws E_OTS_FileLoaderError When error occurs during file operation.
* @throws E_OTS_OutOfBuffer When there is read attemp after end of stream.
*/
public function loadFile($file)
{
// loads file structure
parent::loadFile($file);
// saves directory path for external files
$this->directory = dirname($file);
// parses loaded file
$this->parse();
}
/**
* Parses loaded file.
*
* @version 0.1.0
* @throws E_OTS_FileLoaderError When error occurs during file operation.
* @throws E_OTS_OutOfBuffer When there is read attemp after end of stream.
*/
private function parse()
{
// root node header
$version = $this->root->getLong();
$this->width = $this->root->getShort();
$this->height = $this->root->getShort();
$majorVersionItems = $this->root->getLong();
$minorVersionItems = $this->root->getLong();
// checks version of root node
if($version > 2 || $version <= 0)
{
throw new E_OTS_OTBMError(E_OTS_OTBMError::LOADMAPERROR_OUTDATEDHEADER);
}
// reads root's first child
$node = $this->root->getChild();
// it should be OTBM_NODE_MAP_DATA
if( $node->getType() != self::OTBM_NODE_MAP_DATA)
{
throw new E_OTS_OTBMError(E_OTS_OTBMError::LOADMAPERROR_UNKNOWNNODETYPE);
}
// reads map attributes
while( $node->isValid() )
{
switch( $node->getChar() )
{
// description text
case self::OTBM_ATTR_DESCRIPTION:
$this->description .= $node->getString() . "\n";
break;
// external houses file
case self::OTBM_ATTR_EXT_HOUSE_FILE:
$this->housesList = new OTS_HousesList($this->directory . '/' . $node->getString() );
break;
// external spawns file
case self::OTBM_ATTR_EXT_SPAWN_FILE:
// just we need to skip known attributes
$node->getString();
break;
// unsupported attribute
default:
throw new E_OTS_OTBMError(E_OTS_OTBMError::LOADMAPERROR_UNKNOWNNODETYPE);
}
}
$node = $node->getChild();
// reads map nodes
while($node)
{
switch( $node->getType() )
{
// map definition part
case self::OTBM_NODE_TILE_AREA:
// reads base X, Y and Z coords
$baseX = $node->getShort();
$baseY = $node->getShort();
$z = $node->getChar();
$tile = $node->getChild();
// reads houses tiles
while($tile)
{
// we dont need other tiles at the moment in POT, feel free to add it's suport on yourself
if( $tile->getType() == self::OTBM_NODE_HOUSETILE)
{
// reads tile coords
$offsetX = $tile->getChar();
$offsetY = $tile->getChar();
$coords = new OTS_MapCoords($baseX + $offsetX, $baseY + $offsetY, $z);
// reads house by it's ID
$house = $this->housesList->getHouse( $tile->getLong() );
$house->addTile($coords);
}
$tile = $tile->getNext();
}
break;
// list of towns on map
case self::OTBM_NODE_TOWNS:
$town = $node->getChild();
// reads all towns
while($town)
{
// checks if it's town node
if( $town->getType() != self::OTBM_NODE_TOWN)
{
throw new E_OTS_OTBMError(E_OTS_OTBMError::LOADMAPERROR_UNKNOWNNODETYPE);
}
// reads basic town info
$id = $town->getLong();
$this->towns[$id] = $town->getString();
// temple coords
$x = $town->getShort();
$y = $town->getShort();
$z = $town->getChar();
$this->temples[$id] = new OTS_MapCoords($x, $y, $z);
$town = $town->getNext();
}
break;
// waypoints list
case self::OTBM_NODE_WAYPOINTS:
$waypoint = $node->getChild();
$list = array();
// reads all waypoints
while($waypoint)
{
// checks if it's waypoint
if( $town->getType() != self::OTBM_NODE_WAYPOINT)
{
throw new E_OTS_OTBMError(E_OTS_OTBMError::LOADMAPERROR_UNKNOWNNODETYPE);
}
// reads waypoint name
$name = $town->getString();
// point coords
$x = $town->getShort();
$y = $town->getShort();
$z = $town->getChar();
$list[] = new OTS_Waypoint($name, $x, $y, $z);
$waypoint = $waypoint->getNext();
}
// adds track to waypoints list
$this->waypoints[] = $list;
break;
// unknown type
default:
throw new E_OTS_OTBMError(E_OTS_OTBMError::LOADMAPERROR_UNKNOWNNODETYPE);
}
$node = $node->getNext();
}
}
/**
* Loads map's houses list.
*
* @version 0.1.0
* @since 0.1.0
* @return OTS_HousesList Houses from external file.
*/
public function getHousesList()
{
return $this->housesList;
}
/**
* Returns map width.
*
* @return int Map width.
*/
public function getWidth()
{
return $this->width;
}
/**
* Returns map height.
*
* @return int Map height.
*/
public function getHeight()
{
return $this->height;
}
/**
* Returns map description.
*
* @return string Map description.
*/
public function getDescription()
{
return $this->description;
}
/**
* Returns map waypoints list.
*
* <p>
* Each item of returned array is sub-array with list of waypoints.
* </p>
*
* @version 0.1.6
* @since 0.1.6
* @return array List of tracks.
*/
public function getWaypointsList()
{
return $this->waypoints;
}
/**
* Checks if given town ID exists on list.
*
* @version 0.1.3
* @since 0.1.3
* @param int $id ID.
* @return bool If town is set then true.
*/
public function hasTownId($id)
{
return isset($this->towns[$id]);
}
/**
* Returns town's ID.
*
* @version 0.1.3
* @param string $name Town.
* @return int ID.
* @throws OutOfBoundsException If not found.
*/
public function getTownID($name)
{
$id = array_search($name, $this->towns);
if($id === false)
{
throw new OutOfBoundsException();
}
return $id;
}
/**
* Checks if given town name exists on list.
*
* @version 0.1.3
* @since 0.1.3
* @param string $name Town.
* @return bool If town is set then true.
*/
public function hasTownName($name)
{
return array_search($name, $this->towns) !== false;
}
/**
* Returns name of given town's ID.
*
* @version 0.1.3
* @param int $id Town ID.
* @return string Name.
* @throws OutOfBoundsException If not found.
*/
public function getTownName($id)
{
if( isset($this->towns[$id]) )
{
return $this->towns[$id];
}
throw new OutOfBoundsException();
}
/**
* @return array List of towns.
* @deprecated 0.1.0 Use this class object as array for iterations, counting and methods for field fetching.
*/
public function getTownsList()
{
return $this->towns;
}
/**
* Returns town's temple position.
*
* @param int $id Town id.
* @return OTS_MapCoords|bool Point on map (false if not found).
*/
public function getTownTemple($id)
{
if( isset($this->temples[$id]) )
{
return $this->temples[$id];
}
else
{
return false;
}
}
/**
* Returns amount of towns loaded.
*
* @version 0.0.8
* @since 0.0.8
* @return int Count of towns.
*/
public function count()
{
return count($this->towns);
}
/**
* @version 0.0.8
* @since 0.0.8
* @return string Town name.
* @deprecated 0.1.0 Use getIterator().
*/
public function current()
{
return current($this->towns);
}
/**
* @version 0.0.8
* @since 0.0.8
* @deprecated 0.1.0 Use getIterator().
*/
public function next()
{
next($this->towns);
}
/**
* @version 0.0.8
* @since 0.0.8
* @return int Current position key.
* @deprecated 0.1.0 Use getIterator().
*/
public function key()
{
return key($this->towns);
}
/**
* @version 0.0.8
* @since 0.0.8
* @return bool If iterator has anything more.
* @deprecated 0.1.0 Use getIterator().
*/
public function valid()
{
return key($this->towns) !== null;
}
/**
* @version 0.0.8
* @since 0.0.8
* @deprecated 0.1.0 Use getIterator().
*/
public function rewind()
{
reset($this->towns);
}
/**
* Returns iterator handle for loops.
*
* @version 0.1.0
* @since 0.1.0
* @return ArrayIterator Towns list iterator.
*/
public function getIterator()
{
return new ArrayIterator($this->towns);
}
/**
* Checks if given element exists.
*
* @version 0.1.0
* @since 0.1.0
* @param string|int $offset Array key.
* @return bool True if it's set.
*/
public function offsetExists($offset)
{
// integer key
if( is_int($offset) )
{
return isset($this->towns[$offset]);
}
// town name
else
{
return $this->getTownId($offset) !== false;
}
}
/**
* Returns item from given position.
*
* @version 0.1.0
* @since 0.1.0
* @param string|int $offset Array key.
* @return mixed If key is an integer (type-sensitive!) then returns town name. If it's a string then return associated ID found by town name. False if offset is not set.
*/
public function offsetGet($offset)
{
// integer key
if( is_int($offset) )
{
if( isset($this->towns[$offset]) )
{
return $this->towns[$offset];
}
// keys is not set
else
{
return false;
}
}
// town name
else
{
return $this->getTownId($offset);
}
}
/**
* This method is implemented for ArrayAccess interface. In fact you can't write/append to towns list. Any call to this method will cause {@link E_OTS_ReadOnly E_OTS_ReadOnly} raise.
*
* @version 0.1.0
* @since 0.1.0
* @param string|int $offset Array key.
* @param mixed $value Field value.
* @throws E_OTS_ReadOnly Always - this class is read-only.
*/
public function offsetSet($offset, $value)
{
throw new E_OTS_ReadOnly();
}
/**
* This method is implemented for ArrayAccess interface. In fact you can't write/append to towns list. Any call to this method will cause {@link E_OTS_ReadOnly E_OTS_ReadOnly} raise.
*
* @version 0.1.0
* @since 0.1.0
* @param string|int $offset Array key.
* @throws E_OTS_ReadOnly Always - this class is read-only.
*/
public function offsetUnset($offset)
{
throw new E_OTS_ReadOnly();
}
/**
* Magic PHP5 method.
*
* @version 0.1.0
* @since 0.1.0
* @param string $name Property name.
* @return mixed Property value.
* @throws OutOfBoundsException For non-supported properties.
*/
public function __get($name)
{
switch($name)
{
case 'housesList':
return $this->getHousesList();
case 'width':
return $this->getWidth();
case 'height':
return $this->getHeight();
case 'description':
return $this->getDescription();
case 'waypoints':
return $this->getWaypoints();
default:
throw new OutOfBoundsException();
}
}
/**
* Returns string representation of object.
*
* <p>
* If any display driver is currently loaded then it uses it's method.
* </p>
*
* @version 0.1.3
* @since 0.1.3
* @return string String representation of object.
*/
public function __toString()
{
$ots = POT::getInstance();
// checks if display driver is loaded
if( $ots->isDataDisplayDriverLoaded() )
{
return $ots->getDataDisplayDriver()->displayOTBMMap($this);
}
return (string) $this->count();
}
}
/**#@-*/
?>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,59 @@
<?php
/**
* @package POT
* @version 0.1.5
* @since 0.1.5
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 - 2008 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/
/**
* OTServ player ban.
*
* @package POT
* @version 0.1.5
* @since 0.1.5
*/
class OTS_PlayerBan extends OTS_Ban
{
/**
* Ban data.
*
* @var array
* @version 0.1.5
* @since 0.1.5
*/
private $data = array('type' => POT::BAN_PLAYER, 'param' => 0, 'active' => true, 'admin_id' => 0, 'comment' => '', 'reason' => 0);
/**
* Loads player ban with given id.
*
* @version 0.1.5
* @since 0.1.5
* @param int $id Ban ID.
* @throws PDOException On PDO operation error.
*/
public function load($id)
{
// SELECT query on database
$this->data = $this->db->query('SELECT ' . $this->db->fieldName('id') . ', ' . $this->db->fieldName('type') . ', ' . $this->db->fieldName('value') . ', ' . $this->db->fieldName('param') . ', ' . $this->db->fieldName('active') . ', ' . $this->db->fieldName('expires') . ', ' . $this->db->fieldName('added') . ', ' . $this->db->fieldName('admin_id') . ', ' . $this->db->fieldName('comment') . ', ' . $this->db->fieldName('reason') . ' FROM ' . $this->db->tableName('bans') . ' WHERE ' . $this->db->fieldName('type') . ' = ' . POT::BAN_PLAYER . ' AND ' . $this->db->fieldName('id') . ' = ' . (int) $id)->fetch();
}
/**
* Loads player ban by banned player ID.
*
* @version 0.1.5
* @since 0.1.5
* @param int $id Players's ID.
* @throws PDOException On PDO operation error.
*/
public function find($id)
{
// SELECT query on database
$this->data = $this->db->query('SELECT ' . $this->db->fieldName('id') . ', ' . $this->db->fieldName('type') . ', ' . $this->db->fieldName('value') . ', ' . $this->db->fieldName('param') . ', ' . $this->db->fieldName('active') . ', ' . $this->db->fieldName('expires') . ', ' . $this->db->fieldName('added') . ', ' . $this->db->fieldName('admin_id') . ', ' . $this->db->fieldName('comment') . ', ' . $this->db->fieldName('reason') . ' FROM ' . $this->db->tableName('bans') . ' WHERE ' . $this->db->fieldName('type') . ' = ' . POT::BAN_PLAYER . ' AND ' . $this->db->fieldName('value') . ' = ' . (int) $id)->fetch();
}
}
?>

View File

@@ -0,0 +1,38 @@
<?php
/**
* @package POT
* @version 0.1.5
* @since 0.1.5
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 - 2008 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/
/**
* List of player bans.
*
* @package POT
* @version 0.1.5
* @since 0.1.5
*/
class OTS_PlayerBans_List extends OTS_Bans_List
{
/**
* Initializes list with player bans filtering.
*
* @version 0.1.5
* @since 0.1.5
*/
public function __construct()
{
parent::__construct();
// filters only account bans
$filter = new OTS_SQLFilter();
$filter->addFilter( new OTS_SQLField('type', 'bans'), POT::BAN_PLAYER);
$this->setFilter($filter);
}
}
?>

View File

@@ -0,0 +1,70 @@
<?php
/**
* @package POT
* @version 0.1.3
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 - 2008 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/
/**
* List of players.
*
* @package POT
* @version 0.1.3
*/
class OTS_Players_List extends OTS_Base_List
{
/**
* @version 0.0.5
* @param OTS_Player $player Player to be deleted.
* @deprecated 0.0.5 Use OTS_Player->delete().
*/
public function deletePlayer(OTS_Player $player)
{
$this->db->query('DELETE FROM ' . $this->db->tableName('players') . ' WHERE ' . $this->db->fieldName('id') . ' = ' . $player->getId() );
}
/**
* Sets list parameters.
*
* <p>
* This method is called at object creation.
* </p>
*
* @version 0.0.5
* @since 0.0.5
*/
public function init()
{
$this->table = 'players';
$this->class = 'Player';
}
/**
* Returns string representation of object.
*
* <p>
* If any display driver is currently loaded then it uses it's method.
* </p>
*
* @version 0.1.3
* @since 0.1.0
* @return string String representation of object.
*/
public function __toString()
{
$ots = POT::getInstance();
// checks if display driver is loaded
if( $ots->isDisplayDriverLoaded() )
{
return $ots->getDisplayDriver()->displayPlayersList($this);
}
return (string) $this->count();
}
}
?>

177
system/libs/pot/OTS_RSA.php Normal file
View File

@@ -0,0 +1,177 @@
<?php
/**#@+
* @version 0.1.2
* @since 0.1.2
*/
/**
* @package POT
* @version 0.1.3
* @author Wrzasq <wrzasq@gmail.com>
* @author Alexander Valyalkin <valyala@gmail.com>
* @copyright 2007 - 2008 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
* @license http://www.php.net/license/3_0.txt PHP License, Version 3.0
*/
/**
* RSA encryption/decryption mechanism.
*
* <p>
* This code bases in large part on Alexander Valyalkin'es Crypt_RSA's source code.
* </p>
*
* @package POT
* @version 0.1.3
*/
class OTS_RSA implements IOTS_Cipher
{
/**
* OTServ key part.
*
* @version 0.1.3
* @since 0.1.3
*/
const OTSERV_P = '14299623962416399520070177382898895550795403345466153217470516082934737582776038882967213386204600674145392845853859217990626450972452084065728686565928113';
/**
* OTServ key part.
*
* @version 0.1.3
* @since 0.1.3
*/
const OTSERV_Q = '7630979195970404721891201847792002125535401292779123937207447574596692788513647179235335529307251350570728407373705564708871762033017096809910315212884101';
/**
* OTServ key part.
*
* @version 0.1.3
* @since 0.1.3
*/
const OTSERV_D = '46730330223584118622160180015036832148732986808519344675210555262940258739805766860224610646919605860206328024326703361630109888417839241959507572247284807035235569619173792292786907845791904955103601652822519121908367187885509270025388641700821735345222087940578381210879116823013776808975766851829020659073';
/**
* @deprecated 0.1.3 Use OTS_RSA::P.
*/
const P = self::OTSERV_P;
/**
* @deprecated 0.1.3 Use OTS_RSA::Q.
*/
const Q = self::OTSERV_Q;
/**
* @deprecated 0.1.3 Use OTS_RSA::D.
*/
const D = self::OTSERV_D;
/**
* Keys modulus.
*
* @var string
*/
private $n;
/**
* Private key exponent.
*
* @var string
*/
private $d;
/**
* Public key exponent.
*
* @var string
*/
private $e = '65537';
/**
* Length of keys modulus.
*
* @var int
*/
private $length;
/**
* Initializes new encryption session.
*
* <p>
* If you won't pass any parameters default OTServ keys will be generated. It is recommended action for compatibility with oryginal Tibia servers and clients as well as default Open Tibia implementation.
* </p>
*
* <p>
* Note: You must be sure your <i>p</i>, <i>q</i> and <i>d</i> values are proper for RSA keys generation as class won't change it for you.
* </p>
*
* @param string $p Key part.
* @param string $q Key part.
* @param string $d Key part.
* @throws LogicException When BCMath extension is not loaded.
*/
public function __construct($p = self::OTSERV_P, $q = self::OTSERV_Q, $d = self::OTSERV_D)
{
// checks if required BCMath library is loaded
if( !extension_loaded('bcmath') )
{
throw new LogicException();
}
$this->d = $d;
// computes keys modulus
$this->n = bcmul($p, $q);
// length of key
$tmp = OTS_BinaryTools::int2Bin($this->n);
$this->length = strlen($tmp) * 8;
$tmp = ord($tmp[ strlen($tmp) - 1]);
// if last byte is 0
if($tmp == 0)
{
$this->length -= 8;
}
else
{
// reduces last bits from count
while(!($tmp & 0x80))
{
$this->length--;
$tmp <<= 1;
}
}
}
/**
* Ecnrypts message with RSA algorithm.
*
* @param string $message Message to be encrypted.
* @return string Encrypted message.
*/
public function encrypt($message)
{
// chunk length
$length = ceil($this->length / 8);
// c = m^e mod n
return str_pad( strrev( OTS_BinaryTools::int2Bin( bcpowmod( OTS_BinaryTools::bin2Int( strrev( str_pad($message, $length, chr(0) ) ) ), $this->e, $this->n) ) ), $length, chr(0), STR_PAD_LEFT);
}
/**
* Decrypts RSA-encrypted message.
*
* <p>
* As OTServ clients use RSA encryption only for sending requests we don't need decryption here. If it will be needed, then this method will be implemented. At the moment it will throw exception.
* </p>
*
* @param string $message RSA-encrypted message.
* @return string Decrypted content.
* @throws LogicException Always as this method is not implemented.
*/
public function decrypt($message)
{
throw new LogicException();
}
}
/**#@-*/
?>

View File

@@ -0,0 +1,79 @@
<?php
/**#@+
* @version 0.1.1
* @since 0.1.1
*/
/**
* @package POT
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 - 2008 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/
/**
* Base class for all single-row classes. It implements auto-loading constructors.
*
* <p>
* This class extends {@link OTS_Base_DAO basic DAO class} by initialising interface.
* </p>
*
* <p>
* This class is mostly usefull when you create own extensions for POT code.
* </p>
*
* @package POT
*/
abstract class OTS_Row_DAO extends OTS_Base_DAO
{
/**
* Handles automatic loading for record.
*
* <p>
* You can call class constructor with optional parameter which can be either of integer type (then it will be treated as primary key value) or string type (then it will be used as name identifier).
* </p>
*
* <p>
* Note: Make sure that you pass <var>$id</var> argument of correct type. This method determinates action which should be taken based on variable type. It means that 1 is primary key value, but '1' is name value.
* </p>
*
* @param int|string|null $id Row ID (or name identifier dependend on child class).
*/
public function __construct($id = null)
{
parent::__construct();
// checks if row identifier is set
if( isset($id) )
{
// checks if it's ID, or name identifier
if( is_int($id) )
{
$this->load($id);
}
else
{
$this->find($id);
}
}
}
/**
* Loads row by it's ID.
*
* @param int $id Integer identifier.
*/
abstract public function load($id);
/**
* Loads row by it's name.
*
* @param string $name String identifier.
*/
abstract public function find($name);
}
/**#@-*/
?>

View File

@@ -0,0 +1,125 @@
<?php
/**#@+
* @version 0.0.5
* @since 0.0.5
*/
/**
* @package POT
* @version 0.1.0
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/
/**
* SQL identifier representation.
*
* @package POT
* @version 0.1.0
* @property-read string $name Field name.
* @property-read string $table Table name.
* @tutorial POT/List_objects.pkg#filters.field
*/
class OTS_SQLField
{
/**
* Field name.
*
* @var string
*/
private $name;
/**
* Table name.
*
* @var string
*/
private $table;
/**
* Creates new field representation.
*
* @param string $name Field name.
* @param string $table Table name.
*/
public function __construct($name, $table = '')
{
$this->name = $name;
$this->table = $table;
}
/**
* Returns field name.
*
* @return string Field name.
*/
public function getName()
{
return $this->name;
}
/**
* Returns table name.
*
* @return string Table name.
*/
public function getTable()
{
return $this->table;
}
/**
* Magic PHP5 method.
*
* @version 0.1.0
* @since 0.1.0
* @param string $name Property name.
* @return mixed Property value.
* @throws OutOfBoundsException For non-supported properties.
*/
public function __get($name)
{
switch($name)
{
case 'name':
case 'table':
return $this->$name;
default:
throw new OutOfBoundsException();
}
}
/**
* Returns string representation for WHERE clause.
*
* <p>
* Returned string can be easily inserted into SQL query.
* </p>
*
* @version 0.1.0
* @since 0.1.0
* @return string String WHERE clause.
*/
public function __toString()
{
// database handle
$db = POT::getInstance()->getDBHandle();
// basic name
$name = $db->fieldName($this->name);
// prepends table name
if( !empty($this->table) )
{
$name = $db->tableName($this->table) . '.' . $name;
}
return $name;
}
}
/**#@-*/
?>

View File

@@ -0,0 +1,348 @@
<?php
/**#@+
* @version 0.0.5
* @since 0.0.5
*/
/**
* @package POT
* @version 0.1.3
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/
/**
* SQL WHERE clause object.
*
* <p>
* Objects of this class can be used to filter {@link OTS_Base_List list objects} using {@link OTS_Base_List::setFilter() setFilter() method}. To compose more complex WHERE clauses you can append another filter to this one to create sub-condition.
* </p>
*
* @package POT
* @version 0.1.3
* @property-read array $tables List of tables used by this statement.
* @tutorial POT/List_objects.pkg#filters
*/
class OTS_SQLFilter extends OTS_Base_DAO
{
/**
* Equal operator.
*/
const OPERATOR_EQUAL = 1;
/**
* Lower-then operator.
*/
const OPERATOR_LOWER = 2;
/**
* Greater-then operator.
*/
const OPERATOR_GREATER = 3;
/**
* Not-equal operator.
*/
const OPERATOR_NEQUAL = 4;
/**
* Not-lower-then operator.
*/
const OPERATOR_NLOWER = 5;
/**
* Not-greater-then operator.
*/
const OPERATOR_NGREATER = 6;
/**
* LIKE operator.
*/
const OPERATOR_LIKE = 7;
/**
* Not-LIKE operator.
*/
const OPERATOR_NLIKE = 8;
/**
* AND sibling.
*/
const CRITERIUM_AND = 1;
/**
* OR sibling.
*/
const CRITERIUM_OR = 2;
/**
* List of criteriums.
*
* @var array
*/
private $criteriums = array();
/**
* Magic PHP5 method.
*
* <p>
* Allows object serialisation.
* </p>
*
* @return array List of properties that should be saved.
*/
public function __sleep()
{
return array('criteriums');
}
/**
* Creates clone of object.
*
* <p>
* This method is empty to override {@link OTS_Base_DAO::__clone() OTS_Base_DAO method}.
* </p>
*
* @version 0.1.3
* @since 0.1.3
*/
public function __clone()
{
}
/**
* Returns string representation of WHERE clause.
*
* <p>
* Returned string can be easily inserted into SQL query.
* </p>
*
* @version 0.1.0
* @return string String WHERE clause.
*/
public function __toString()
{
$where = '';
// first filter element
$first = true;
// inserts filters into string
foreach($this->criteriums as $criterium)
{
// next elements merged
if(!$first)
{
switch($criterium['criterium'])
{
case self::CRITERIUM_AND:
$where .= ' AND ';
break;
case self::CRITERIUM_OR:
$where .= ' OR ';
break;
}
}
else
{
$first = false;
}
// sub-filter
if($criterium['left'] instanceof OTS_SQLFilter)
{
$where .= '(' . $criterium['left']->__toString() . ')';
}
// single criterium
else
{
// left side
if($criterium['left'] instanceof OTS_SQLField)
{
$where .= $criterium['left']->__toString();
}
else
{
if( is_int($criterium['left']) || is_float($criterium['left']) )
{
$where .= $criterium['left'];
}
// quotes string
else
{
$where .= $this->db->quote($criterium['left']);
}
}
// appends operator
switch($criterium['operator'])
{
case self::OPERATOR_EQUAL:
$where .= ' = ';
break;
case self::OPERATOR_LOWER:
$where .= ' < ';
break;
case self::OPERATOR_GREATER:
$where .= ' > ';
break;
case self::OPERATOR_NEQUAL:
$where .= ' != ';
break;
case self::OPERATOR_NLOWER:
$where .= ' >= ';
break;
case self::OPERATOR_NGREATER:
$where .= ' <= ';
break;
case self::OPERATOR_LIKE:
$where .= ' LIKE ';
break;
case self::OPERATOR_NLIKE:
$where .= ' NOT LIKE ';
break;
}
// right side
if($criterium['right'] instanceof OTS_SQLField)
{
$where .= $criterium['right']->__toString();
}
else
{
if( is_int($criterium['right']) || is_float($criterium['right']) )
{
$where .= $criterium['right'];
}
// quotes string
else
{
$where .= $this->db->quote($criterium['right']);
}
}
}
}
return $where;
}
/**
* General-purpose filter.
*
* <p>
* Appends new filter in universal way. You can append either literal value comparsion, fields comparsion or another filter object as sub-condition.
* </p>
*
* <p>
* To append subset of another filters use addFilter($OTS_SQLFilterObject).
* </p>
*
* @param mixed $left Left side ({@link OTS_SQLField OTS_SQLField class} object, {@link OTS_SQLFilter OTS_SQLFilter class} object, or literal value).
* @param mixed $right Right side ({@link OTS_SQLField OTS_SQLField class} object, or literal value).
* @param int $operator Operator used for comparsion (equal check by default).
* @param int $criterium Criterium merging method (AND by default).
*/
public function addFilter($left, $right = null, $operator = self::OPERATOR_EQUAL, $criterium = self::CRITERIUM_AND)
{
$this->criteriums[] = array('left' => $left, 'right' => $right, 'operator' => $operator, 'criterium' => $criterium);
}
/**
* Compares field with a literal value.
*
* @param string $field Field name.
* @param mixed $value Literal value.
* @param int $operator Operator used for comparsion (equal by default).
* @param int $criterium Criterium merging method (AND by default).
* @example examples/filter.php filter.php
*/
public function compareField($field, $value, $operator = self::OPERATOR_EQUAL, $criterium = self::CRITERIUM_AND)
{
$this->addFilter( new OTS_SQLField($field), $value, $operator, $criterium);
}
/**
* Returns list of all tables used by filter.
*
* <p>
* This is required for FROM clause.
* </p>
*
* @return array List of all tables used by this filter.
*/
public function getTables()
{
$tables = array();
// finds all unique table names
foreach($this->criteriums as $criterium)
{
// subcriterium
if($criterium['left'] instanceof OTS_SQLFilter)
{
// puts all it's tables into current list
foreach( $criterium['left']->getTables() as $table)
{
// checks if it's not default table neither already saved table
if(!( empty($table) || in_array($table, $tables) ))
{
$tables[] = $table;
}
}
}
// field name on left side
if($criterium['left'] instanceof OTS_SQLField)
{
$table = $criterium['left']->getTable();
// checks if it's not default table neither already saved table
if(!( empty($table) || in_array($table, $tables) ))
{
$tables[] = $table;
}
}
// field name on right side
if($criterium['right'] instanceof OTS_SQLField)
{
$table = $criterium['right']->getTable();
// checks if it's not default table neither already saved table
if(!( empty($table) || in_array($table, $tables) ))
{
$tables[] = $table;
}
}
}
return $tables;
}
/**
* Magic PHP5 method.
*
* @version 0.1.0
* @since 0.1.0
* @param string $name Property name.
* @return mixed Property value.
* @throws OutOfBoundsException For non-supported properties.
*/
public function __get($name)
{
switch($name)
{
case 'tables':
return $this->getTables();
default:
throw new OutOfBoundsException();
}
}
}
/**#@-*/
?>

View File

@@ -0,0 +1,227 @@
<?php
/**#@+
* @version 0.1.4
* @since 0.1.4
*/
/**
* @package POT
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 - 2008 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/
/**
* Various server status querying methods.
*
* @package POT
* @property-read OTS_InfoRespond|bool $status status() method wrapper.
* @property-read OTS_ServerStatus|bool $info Full info() method wrapper.
*/
class OTS_ServerInfo
{
/**
* Server address.
*
* @var string
*/
private $server;
/**
* Connection port.
*
* @var int
*/
private $port;
/**
* Creates handler for new server.
*
* @param string $server Server IP/domain.
* @param int $port OTServ port.
*/
public function __construct($server, $port)
{
$this->server = $server;
$this->port = $port;
}
/**
* Sends packet to server.
*
* @param OTS_Buffer $packet Buffer to send.
* @return OTS_Buffer|null Respond buffer (null if server is offline).
* @throws E_OTS_OutOfBuffer When there is read attemp after end of packet stream.
*/
private function send(OTS_Buffer $packet)
{
// connects to server
// gives maximum 5 seconds to connect
$socket = @fsockopen($this->server, $this->port, $error, $message, 5);
// if connected then checking statistics
if($socket)
{
// sets 5 second timeout for reading and writing
stream_set_timeout($socket, 5);
// creates real packet
$packet = $packet->getBuffer();
$packet = pack('v', strlen($packet) ) . $packet;
// sends packet with request
// 06 - length of packet, 255, 255 is the comamnd identifier, 'info' is a request
fwrite($socket, $packet);
// reads respond
$data = stream_get_contents($socket);
// closing connection to current server
fclose($socket);
// sometimes server returns empty info
if( empty($data) )
{
// returns offline state
return false;
}
return new OTS_Buffer($data);
}
return false;
}
/**
* Queries server status.
*
* <p>
* Sends 'info' packet to OTS server and return output. Returns {@link OTS_InfoRespond OTS_InfoRespond} (wrapper for XML data) with results or <var>false</var> if server is online.
* </p>
*
* @return OTS_InfoRespond|bool Respond content document (false when server is offline).
* @throws DOMException On DOM operation error.
* @throws E_OTS_OutOfBuffer When there is read attemp after end of packet stream.
* @example examples/info.php info.php
* @tutorial POT/Server_status.pkg
*/
public function status()
{
// request packet
$request = new OTS_Buffer();
$request->putChar(255);
$request->putChar(255);
$request->putString('info', false);
$status = $this->send($request);
// checks if server is online
if($status)
{
// loads respond XML
$info = new OTS_InfoRespond();
$info->loadXML( $status->getBuffer() );
return $info;
}
// offline
return false;
}
/**
* Queries server information.
*
* <p>
* This method uses binary info protocol. It provides more infromation then {@link OTS_Toolbox::serverStatus() XML way}.
* </p>
*
* @param int $flags Requested info flags.
* @return OTS_ServerStatus|bool Respond content document (false when server is offline).
* @throws E_OTS_OutOfBuffer When there is read attemp after end of packet stream.
* @example examples/server.php info.php
* @tutorial POT/Server_status.pkg
*/
public function info($flags)
{
// request packet
$request = new OTS_Buffer();
$request->putChar(255);
$request->putChar(1);
$request->putShort($flags);
$status = $this->send($request);
// checks if server is online
if($status)
{
// loads respond
return new OTS_ServerStatus($status);
}
// offline
return false;
}
/**
* Checks player online status.
*
* <p>
* This method uses binary info protocol.
* </p>
*
* @param string $name Player name.
* @return bool True if player is online, false if player or server is online.
* @throws E_OTS_OutOfBuffer When there is read attemp after end of packet stream.
* @example examples/server.php info.php
* @tutorial POT/Server_status.pkg
*/
public function playerStatus($name)
{
// request packet
$request = new OTS_Buffer();
$request->putChar(255);
$request->putChar(1);
$request->putShort(OTS_ServerStatus::REQUEST_PLAYER_STATUS_INFO);
$request->putString($name);
$status = $this->send($request);
// checks if server is online
if($status)
{
$status->getChar();
return (bool) $status->getChar();
}
// offline
return false;
}
/**
* Magic PHP5 method.
*
* @param string $name Property name.
* @param mixed $value Property value.
* @throws OutOfBoundsException For non-supported properties.
* @throws E_OTS_OutOfBuffer When there is read attemp after end of packet stream.
*/
public function __get($name)
{
switch($name)
{
case 'status':
return $this->status();
case 'info':
return $this->info(OTS_ServerStatus::REQUEST_BASIC_SERVER_INFO | OTS_ServerStatus::REQUEST_OWNER_SERVER_INFO | OTS_ServerStatus::REQUEST_MISC_SERVER_INFO | OTS_ServerStatus::REQUEST_PLAYERS_INFO | OTS_ServerStatus::REQUEST_MAP_INFO | OTS_ServerStatus::REQUEST_PLAYER_STATUS_INFO);
default:
throw new OutOfBoundsException();
}
}
}
/**#@-*/
?>

View File

@@ -0,0 +1,572 @@
<?php
/**#@+
* @version 0.1.4
* @since 0.1.4
*/
/**
* @package POT
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/
/**
* Wrapper for binary server status request.
*
* @package POT
* @property-read int $uptime Uptime.
* @property-read string $ip IP number.
* @property-read string $name Server name.
* @property-read int $port Server port.
* @property-read string $location Server physical location.
* @property-read string $url Website URL.
* @property-read string $serverVersion Server version.
* @property-read string $owner Owner name.
* @property-read string $eMail Owner's e-mail.
* @property-read int $onlinePlayers Players online count.
* @property-read int $maxPlayers Maximum allowed players count.
* @property-read int $playersPeak Record of players online.
* @property-read string $mapName Map name.
* @property-read string $mapAuthor Map author.
* @property-read int $mapWidth Map width.
* @property-read int $mapHeight Map height.
* @property-read string $motd Message Of The Day.
* @property-read array $players Online players list.
*/
class OTS_ServerStatus
{
/**
* Basic server info.
*/
const REQUEST_BASIC_SERVER_INFO = 1;
/**
* Server owner info.
*/
const REQUEST_OWNER_SERVER_INFO = 2;
/**
* Server extra info.
*/
const REQUEST_MISC_SERVER_INFO = 4;
/**
* Players stats info.
*/
const REQUEST_PLAYERS_INFO = 8;
/**
* Map info.
*/
const REQUEST_MAP_INFO = 16;
/**
* Extended players info.
*/
const REQUEST_EXT_PLAYERS_INFO = 32;
/**
* Player status info.
*/
const REQUEST_PLAYER_STATUS_INFO = 64;
/**
* Server software info.
*/
const REQUEST_SERVER_SOFTWARE_INFO = 128;
/**
* Basic server respond.
*/
const RESPOND_BASIC_SERVER_INFO = 0x10;
/**
* Server owner respond.
*/
const RESPOND_OWNER_SERVER_INFO = 0x11;
/**
* Server extra respond.
*/
const RESPOND_MISC_SERVER_INFO = 0x12;
/**
* Players stats respond.
*/
const RESPOND_PLAYERS_INFO = 0x20;
/**
* Map respond.
*/
const RESPOND_MAP_INFO = 0x30;
/**
* Extended players info.
*/
const RESPOND_EXT_PLAYERS_INFO = 0x21;
/**
* Player status info.
*/
const RESPOND_PLAYER_STATUS_INFO = 0x22;
/**
* Server software info.
*/
const REQUEST_SERVER_SOFTWARE_INFO = 0x23;
/**
* Server name.
*
* @var string
*/
private $name;
/**
* Server IP.
*
* @var string
*/
private $ip;
/**
* Server port.
*
* @var string
*/
private $port;
/**
* Owner name.
*
* @var string
*/
private $owner;
/**
* Owner's e-mail.
*
* @var string
*/
private $eMail;
/**
* Message of the day.
*
* @var stirng
*/
private $motd;
/**
* Server location.
*
* @var string
*/
private $location;
/**
* Website URL.
*
* @var stirng
*/
private $url;
/**
* Uptime.
*
* @var int
*/
private $uptime;
/**
* Status version.
*
* @var string
*/
private $version;
/**
* Players online.
*
* @var int
*/
private $online;
/**
* Maximum players.
*
* @var int
*/
private $max;
/**
* Players peak.
*
* @var int
*/
private $peak;
/**
* Map name.
*
* @var string
*/
private $map;
/**
* Map author.
*
* @var string
*/
private $author;
/**
* Map width.
*
* @var int
*/
private $width;
/**
* Map height.
*
* @var int
*/
private $height;
/**
* Players online list.
*
* @var array
*/
private $players = array();
/**
* Server software.
*
* @var string
*/
private $softwareName;
private $softwareVersion;
private $softwareProtocol;
/**
* Reads info from respond packet.
*
* @param OTS_Buffer $info Information packet.
*/
public function __construct(OTS_Buffer $info)
{
// skips packet length
$info->getShort();
while( $info->isValid() )
{
switch( $info->getChar() )
{
case self::RESPOND_BASIC_SERVER_INFO:
$this->name = $info->getString();
$this->ip = $info->getString();
$this->port = (int) $info->getString();
break;
case self::RESPOND_OWNER_SERVER_INFO:
$this->owner = $info->getString();
$this->eMail = $info->getString();
break;
case self::RESPOND_MISC_SERVER_INFO:
$this->motd = $info->getString();
$this->location = $info->getString();
$this->url = $info->getString();
$uptime = $info->getLong() << 32;
$this->uptime += $info->getLong() + $uptime;
$this->version = $info->getString();
break;
case self::RESPOND_PLAYERS_INFO:
$this->online = $info->getLong();
$this->max = $info->getLong();
$this->peak = $info->getLong();
break;
case self::RESPOND_MAP_INFO:
$this->map = $info->getString();
$this->author = $info->getString();
$this->width = $info->getShort();
$this->height = $info->getShort();
break;
case self::RESPOND_EXT_PLAYERS_INFO:
$count = $info->getLong();
for($i = 0; $i < $count; $i++)
{
$name = $info->getString();
$this->players[$name] = $info->getLong();
}
break;
case self::REQUEST_SERVER_SOFTWARE_INFO:
$this->softwareName = $info->getString();
$this->softwareVersion = $info->getString();
$this->softwareProtocol = $info->getString();
break;
}
}
}
/**
* Returns server uptime.
*
* @return int Uptime.
*/
public function getUptime()
{
return $this->uptime;
}
/**
* Returns server IP.
*
* @return string IP.
*/
public function getIP()
{
return $this->ip;
}
/**
* Returns server name.
*
* @return string Name.
*/
public function getName()
{
return $this->name;
}
/**
* Returns server port.
*
* @return int Port.
*/
public function getPort()
{
return $this->port;
}
/**
* Returns server location.
*
* @return string Location.
*/
public function getLocation()
{
return $this->location;
}
/**
* Returns server website.
*
* @return string Website URL.
*/
public function getURL()
{
return $this->url;
}
/**
* Returns server version.
*
* @return string Version.
*/
public function getServerVersion()
{
return $this->version;
}
/**
* Returns owner name.
*
* @return string Owner name.
*/
public function getOwner()
{
return $this->owner;
}
/**
* Returns owner e-mail.
*
* @return string Owner e-mail.
*/
public function getEMail()
{
return $this->eMail;
}
/**
* Returns current amount of players online.
*
* @return int Count of players.
*/
public function getOnlinePlayers()
{
return $this->online;
}
/**
* Returns maximum amount of players online.
*
* @return int Maximum allowed count of players.
*/
public function getMaxPlayers()
{
return $this->max;
}
/**
* Returns record of online players.
*
* @return int Players online record.
*/
public function getPlayersPeak()
{
return $this->peak;
}
/**
* Returns map name.
*
* @return string Map name.
*/
public function getMapName()
{
return $this->map;
}
/**
* Returns map author.
*
* @return string Mapper name.
*/
public function getMapAuthor()
{
return $this->author;
}
/**
* Returns map width.
*
* @return int Map width.
*/
public function getMapWidth()
{
return $this->width;
}
/**
* Returns map height.
*
* @return int Map height.
*/
public function getMapHeight()
{
return $this->height;
}
/**
* Returns server's Message Of The Day
*
* @return string Server MOTD.
*/
public function getMOTD()
{
return $this->motd;
}
/**
* Returns list of players currently online.
*
* @return array List of players in format 'name' => level.
*/
public function getPlayers()
{
}
/**
* Returns software name.
*
* @return string Software name.
*/
public function getSoftwareName()
{
return $this->softwareName;
}
/**
* Returns software version.
*
* @return string Software version.
*/
public function getSoftwareVersion()
{
return $this->softwareVersion;
}
/**
* Returns software protocol.
*
* @return string Software protocol.
*/
public function getSoftwareProtocol()
{
return $this->softwareProtocol;
}
/**
* Magic PHP5 method.
*
* @param string $name Property name.
* @return mixed Property value.
* @throws OutOfBoundsException For non-supported properties.
*/
public function __get($name)
{
switch($name)
{
case 'uptime':
return $this->getUptime();
case 'ip':
return $this->getIP();
case 'name':
return $this->getName();
case 'port':
return $this->getPort();
case 'location':
return $this->getLocation();
case 'url':
return $this->getURL();
case 'serverVersion':
return $this->getServerVersion();
case 'owner':
return $this->getOwner();
case 'eMail':
return $this->getEMail();
case 'onlinePlayers':
return $this->getOnlinePlayers();
case 'maxPlayers':
return $this->getMaxPlayers();
case 'playersPeak':
return $this->getPlayersPeak();
case 'mapName':
return $this->getMapName();
case 'mapAuthor':
return $this->getMapAuthor();
case 'mapWidth':
return $this->getMapWidth();
case 'mapHeight':
return $this->getMapHeight();
case 'motd':
return $this->getMOTD();
case 'players':
return $this->getPlayers();
default:
throw new OutOfBoundsException();
}
}
}
/**#@-*/
?>

View File

@@ -0,0 +1,455 @@
<?php
/**#@+
* @version 0.0.7
* @since 0.0.7
*/
/**
* @package POT
* @version 0.1.3
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 - 2008 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/
/**
* Wrapper for spell info.
*
* @package POT
* @version 0.1.3
* @property-read int $type Spell type.
* @property-read string $name Spell name.
* @property-read int $id Spell ID.
* @property-read string $words Spell formula.
* @property-read bool $agressive Does spell marks action as an attack.
* @property-read int $charges Rune charges count.
* @property-read int $level Required level.
* @property-read int $magicLevel Required magic level.
* @property-read int $mana Mana usage.
* @property-read int $soul Soul points usage.
* @property-read bool $hasParams Does spell has any arguments.
* @property-read bool $enabled Is spell enabled.
* @property-read bool $farUseAllowed Can the spell be used from distance.
* @property-read bool $premium Does spell requires PACC.
* @property-read bool $learnNeeded Does the spell needs to be learned.
* @property-read OTS_ItemType|null $conjure Conjure item type.
* @property-read OTS_ItemType|null $reagent Item required to cast this spell.
* @property-read int $conjuresCount Amount of items created with conjure cast.
* @property-read array $vocations List of vocations allowed to use.
*/
class OTS_Spell
{
/**
* Spell type.
*
* @var int
*/
private $type;
/**
* Spell info resource.
*
* @var DOMElement
*/
private $element;
/**
* Sets spell info.
*
* @param int $type Spell type.
* @param DOMElement $spell Spell info.
*/
public function __construct($type, DOMElement $spell)
{
$this->type = $type;
$this->element = $spell;
}
/**
* Returns spell type.
*
* @return int Spell type.
*/
public function getType()
{
return $this->type;
}
/**
* Returns spell name.
*
* @return string Name.
* @throws DOMException On DOM operation error.
*/
public function getName()
{
return $this->element->getAttribute('name');
}
/**
* Returns rune item id.
*
* @return int Rune item ID.
* @throws DOMException On DOM operation error.
*/
public function getID()
{
return (int) $this->element->getAttribute('id');
}
/**
* Returns spell formula.
*
* @return string Formula.
* @throws DOMException On DOM operation error.
*/
public function getWords()
{
return $this->element->getAttribute('words');
}
/**
* Checks if spell is threated as unfriendly by other creatures.
*
* @version 0.1.0
* @since 0.1.0
* @return bool Is spell aggressive.
* @throws DOMException On DOM operation error.
*/
public function isAggressive()
{
return $this->element->getAttribute('aggressive') != '0';
}
/**
* @version 0.1.0
* @return bool Is spell aggressive.
* @deprecated 0.1.0 Use isAggressive().
*/
public function isAggresive()
{
return $this->isAggressive();
}
/**
* Number of rune charges.
*
* @return int Rune charges.
* @throws DOMException On DOM operation error.
*/
public function getCharges()
{
return (int) $this->element->getAttribute('charges');
}
/**
* Level required for use.
*
* @return int Required level.
* @throws DOMException On DOM operation error.
*/
public function getLevel()
{
return (int) $this->element->getAttribute('lvl');
}
/**
* Magic level required to cast.
*
* @return int Required magic level.
* @throws DOMException On DOM operation error.
*/
public function getMagicLevel()
{
return (int) $this->element->getAttribute('maglv');
}
/**
* Mana cost.
*
* @return int Mana usage.
* @throws DOMException On DOM operation error.
*/
public function getMana()
{
return (int) $this->element->getAttribute('mana');
}
/**
* Soul points cost.
*
* @return int Soul points usage.
* @throws DOMException On DOM operation error.
*/
public function getSoul()
{
return (int) $this->element->getAttribute('soul');
}
/**
* Checks if spell has parameter.
*
* @return bool True if spell takes a parameter.
* @throws DOMException On DOM operation error.
*/
public function hasParams()
{
return $this->element->getAttribute('params') == '1';
}
/**
* Checks if spell is enabled.
*
* @return bool Is spell enabled.
* @throws DOMException On DOM operation error.
*/
public function isEnabled()
{
return $this->element->getAttribute('enabled') != '0';
}
/**
* Checks if distance use allowed.
*
* @return bool Is it possible to use this spell from distance.
* @throws DOMException On DOM operation error.
*/
public function isFarUseAllowed()
{
return $this->element->getAttribute('allowfaruse') == '1';
}
/**
* Checks if spell requires PACC.
*
* @return bool Is spell only for Premium Account.
* @throws DOMException On DOM operation error.
*/
public function isPremium()
{
return $this->element->getAttribute('prem') == '1';
}
/**
* Checks if spell needs to be learned.
*
* @return bool Does this spell need to be learned.
* @throws DOMException On DOM operation error.
*/
public function isLearnNeeded()
{
return $this->element->getAttribute('needlearn') == '1';
}
/**
* @return int Item ID.
* @deprecated 0.1.0 Use getConjure()->getId().
*/
public function getConjureId()
{
return (int) $this->element->getAttribute('conjureId');
}
/**
* Returns item type of conjured item.
*
* <p>
* Note: You need to have global items list resource loaded in order to use this method.
* </p>
*
* @version 0.1.0
* @since 0.1.0
* @return OTS_ItemType|null Returns item type of conjure item (null if not exists).
* @throws E_OTS_NotLoaded When there is no global items list available.
* @throws DOMException On DOM operation error.
*/
public function getConjure()
{
return POT::getInstance()->getItemsList()->getItemType( (int) $this->element->getAttribute('conjureId') );
}
/**
* @return int Reagent ID.
* @deprecated 0.1.0 Use getReagent()->getId().
*/
public function getReagentId()
{
return (int) $this->element->getAttribute('reagentId');
}
/**
* Returns item type of reagent item.
*
* <p>
* Note: You need to have global items list resource loaded in order to use this method.
* </p>
*
* @version 0.1.0
* @since 0.1.0
* @return OTS_ItemType|null Returns item type of reagent item (null if not exists).
* @throws E_OTS_NotLoaded When there is no global items list available.
* @throws DOMException On DOM operation error.
*/
public function getReagent()
{
return POT::getInstance()->getItemsList()->getItemType( (int) $this->element->getAttribute('reagentId') );
}
/**
* Returns amount of items conjured by this spell.
*
* @return int Items count.
* @throws DOMException On DOM operation error.
*/
public function getConjureCount()
{
return (int) $this->element->getAttribute('conjureCount');
}
/**
* Returns list of vocations that are allowed to learn this spell.
*
* @return array List of vocation names.
* @throws DOMException On DOM operation error.
*/
public function getVocations()
{
$vocations = array();
foreach( $this->element->getElementsByTagName('vocation') as $vocation)
{
if($vocation->getAttribute('id') != NULL)
$vocations[] = $vocation->getAttribute('id');
else
$vocations[] = $vocation->getAttribute('name');
}
return $vocations;
}
/**
* Creates conjure item.
*
* <p>
* Note: You need to have global items list resource loaded in order to use this method.
* </p>
*
* @version 0.1.0
* @since 0.1.0
* @return OTS_Item Conjured item.
* @throws E_OTS_NotLoaded When there is no global items list available.
* @throws DOMException On DOM operation error.
*/
public function createConjure()
{
$item = $this->getConjure()->createItem();
$item->setCount( $this->getConjureCount() );
return $item;
}
/**
* Magic PHP5 method.
*
* @version 0.1.0
* @since 0.1.0
* @param string $name Property name.
* @return mixed Property value.
* @throws E_OTS_NotLoaded When there is no global items list available.
* @throws OutOfBoundsException For non-supported properties.
* @throws DOMException On DOM operation error.
*/
public function __get($name)
{
switch($name)
{
case 'type':
return $this->getType();
case 'name':
return $this->getName();
case 'id':
return $this->getId();
case 'words':
return $this->getWords();
case 'aggressive':
return $this->isAggressive();
case 'charges':
return $this->getCharges();
case 'level':
return $this->getLevel();
case 'magicLevel':
return $this->getMagicLevel();
case 'mana':
return $this->getMana();
case 'soul':
return $this->getSoul();
case 'hasParams':
return $this->hasParams();
case 'enabled':
return $this->isEnabled();
case 'farUseAllowed':
return $this->isFarUseAllowed();
case 'premium':
return $this->isPremium();
case 'learnNeeded':
return $this->isLearnNeeded();
case 'conjure':
return $this->getConjure();
case 'reagent':
return $this->getReagent();
case 'conjuresCount':
return $this->getConjuresCount();
case 'vocations':
return $this->getVocations();
default:
throw new OutOfBoundsException();
}
}
/**
* Returns string representation of XML.
*
* <p>
* If any display driver is currently loaded then it uses it's method. Otherwise just returns spell XML format.
* </p>
*
* @version 0.1.3
* @since 0.1.0
* @return string String representation of object.
*/
public function __toString()
{
$ots = POT::getInstance();
// checks if display driver is loaded
if( $ots->isDataDisplayDriverLoaded() )
{
return $ots->getDataDisplayDriver()->displaySpell($this);
}
return $this->element->ownerDocument->saveXML($this->element);
}
}
/**#@-*/
?>

View File

@@ -0,0 +1,326 @@
<?php
/**#@+
* @version 0.1.0
* @since 0.1.0
*/
/**
* @package POT
* @version 0.1.5
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 - 2008 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/
/**
* Wrapper for spells list.
*
* <p>
* Note: Unlike other lists classes this one doesn't implement ArrayAccess interface because it contains three kinds of spells grouped into pararell arrays.
* </p>
*
* @package POT
* @version 0.1.5
* @property-read array $runesList List of rune spells.
* @property-read array $instantsList List of instant spells.
* @property-read array $conjuresList List of conjure spells.
* @tutorial POT/data_directory.pkg#spells
*/
class OTS_SpellsList implements IteratorAggregate, Countable
{
/**
* Rune spell.
*/
const SPELL_RUNE = 0;
/**
* Instant spell.
*/
const SPELL_INSTANT = 1;
/**
* Conjure spell.
*/
const SPELL_CONJURE = 2;
/**
* Rune spells.
*
* @var array
*/
private $runes = array();
/**
* Instant spells.
*
* @var array
*/
private $instants = array();
/**
* Conjure spells.
*
* @var array
*/
private $conjures = array();
/**
* Magic PHP5 method.
*
* <p>
* Allows object importing from {@link http://www.php.net/manual/en/function.var-export.php var_export()}.
* </p>
*
* @param array $properties List of object properties.
*/
public function __set_state($properties)
{
$object = new self();
// loads properties
foreach($properties as $name => $value)
{
$object->$name = $value;
}
return $object;
}
/**
* Loads spells list.
*
* @param string $file Spells file name.
* @throws DOMException On DOM operation error.
*/
public function __construct($file)
{
// loads DOM document
$spells = new DOMDocument();
$spells->load($file);
// loads runes
foreach( $spells->getElementsByTagName('rune') as $rune)
{
$this->runes[ $rune->getAttribute('name') ] = new OTS_Spell(self::SPELL_RUNE, $rune);
}
// loads instants
foreach( $spells->getElementsByTagName('instant') as $instant)
{
$this->instants[ $instant->getAttribute('name') ] = new OTS_Spell(self::SPELL_INSTANT, $instant);
}
// loads conjures
foreach( $spells->getElementsByTagName('conjure') as $conjure)
{
$this->conjures[ $conjure->getAttribute('name') ] = new OTS_Spell(self::SPELL_CONJURE, $conjure);
}
}
/**
* Returns list of runes.
*
* @return array List of rune names.
*/
public function getRunesList()
{
return array_keys($this->runes);
}
/**
* Checks if rune exists.
*
* @version 0.1.3
* @since 0.1.3
* @param string $name Rune name.
* @return bool If rune is set then true.
*/
public function hasRune($name)
{
return isset($this->runes[$name]);
}
/**
* Returns given rune spell.
*
* @version 0.1.3
* @param string $name Rune name.
* @return OTS_Spell Rune spell wrapper.
* @throws OutOfBoundsException If rune does not exist.
*/
public function getRune($name)
{
if( isset($this->runes[$name]) )
{
return $this->runes[$name];
}
throw new OutOfBoundsException();
}
/**
* Returns list of instants.
*
* @return array List of instant spells names.
*/
public function getInstantsList()
{
return array_keys($this->instants);
}
/**
* Checks if instant exists.
*
* @version 0.1.3
* @since 0.1.3
* @param string $name Instant name.
* @return bool If instant is set then true.
*/
public function hasInstant($name)
{
return isset($this->instants[$name]);
}
/**
* Returns given instant spell.
*
* @version 0.1.3
* @param string $name Spell name.
* @return OTS_Spell Instant spell wrapper.
* @throws OutOfBoundsException If instant does not exist.
*/
public function getInstant($name)
{
if( isset($this->instants[$name]) )
{
return $this->instants[$name];
}
throw new OutOfBoundsException();
}
/**
* Returns list of conjure spells.
*
* @return array List of conjure spells names.
*/
public function getConjuresList()
{
return array_keys($this->conjures);
}
/**
* Checks if conjure exists.
*
* @version 0.1.3
* @since 0.1.3
* @param string $name Conjure name.
* @return bool If conjure is set then true.
*/
public function hasConjure($name)
{
return isset($this->conjures[$name]);
}
/**
* Returns given conjure spell.
*
* @version 0.1.3
* @param string $name Spell name.
* @return OTS_Spell Conjure spell wrapper.
* @throws OutOfBoundsException If conjure does not exist.
*/
public function getConjure($name)
{
if( isset($this->conjures[$name]) )
{
return $this->conjures[$name];
}
throw new OutOfBoundsException();
}
/**
* Magic PHP5 method.
*
* @param string $name Property name.
* @return mixed Property value.
* @throws OutOfBoundsException For non-supported properties.
*/
public function __get($name)
{
switch($name)
{
case 'runesList':
return $this->getRunesList();
case 'instantsList':
return $this->getInstantsList();
case 'conjuresList':
return $this->getConjuresList();
default:
throw new OutOfBoundsException();
}
}
/**
* Returns string representation of object.
*
* <p>
* If any display driver is currently loaded then it uses it's method.
* </p>
*
* @version 0.1.3
* @since 0.1.3
* @return string String representation of object.
*/
public function __toString()
{
$ots = POT::getInstance();
// checks if display driver is loaded
if( $ots->isDataDisplayDriverLoaded() )
{
return $ots->getDataDisplayDriver()->displaySpellsList($this);
}
return (string) $this->count();
}
/**
* Iterator for all spells.
*
* <p>
* Returned object will continousely iterate through all kind of spells.
* </p>
*
* @version 0.1.5
* @since 0.1.5
* @return AppendIterator Iterator for all spells.
*/
public function getIterator()
{
$iterator = new AppendIterator();
$iterator->append( new ArrayIterator($this->runes) );
$iterator->append( new ArrayIterator($this->instants) );
$iterator->append( new ArrayIterator($this->conjures) );
return $iterator;
}
/**
* Number of all loaded spells.
*
* @version 0.1.5
* @since 0.1.5
* @return int Amount of all spells.
*/
public function count()
{
return count($this->runes) + count($this->instants) + count($this->conjures);
}
}
/**#@-*/
?>

View File

@@ -0,0 +1,119 @@
<?php
/**#@+
* @version 0.1.1
* @since 0.1.1
*/
/**
* @package POT
* @version 0.1.5
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 - 2008 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/
/**
* Toolbox for common operations.
*
* @package POT
* @version 0.1.5
*/
class OTS_Toolbox
{
/**
* Calculates experience points needed for given level.
*
* @param int $level Level for which experience should be calculated.
* @param int $experience Current experience points.
* @return int Experience points for level.
*/
public static function experienceForLevel($level, $experience = 0)
{
return 50 * ($level - 1) * ($level * $level - 5 * $level + 12) / 3 - $experience;
/*
$level = $level - 1;
return ((50 * $level * $level * $level) - (150 * $level * $level) + (400 * $level)) / 3;
*/
}
/**
* Finds out which level user have basing on his/her experience.
*
* <p>
* PHP doesn't support complex numbers natively so solving third-level polynomials would be quite hard. Rather then doing this, this method iterates calculating experience for next levels until it finds one which requires enought experience we have. Because of that, for high experience values this function can take relatively long time to be executed.
* </p>
*
* @param int $experience Current experience points.
* @return int Experience level.
*/
public static function levelForExperience($experience)
{
// default level
$level = 1;
// until we will find level which requires more experience then we have we will step to next
while( self::experienceForLevel($level + 1) <= $experience)
{
$level++;
}
return $level;
}
/**
* @version 0.1.5
* @since 0.1.3
* @return OTS_Players_List Filtered list.
* @deprecated 0.1.5 Use OTS_PlayerBans_List.
*/
public static function bannedPlayers()
{
// creates filter
$filter = new OTS_SQLFilter();
$filter->addFilter( new OTS_SQLField('type', 'bans'), POT::BAN_PLAYER);
$filter->addFilter( new OTS_SQLField('active', 'bans'), 1);
$filter->addFilter( new OTS_SQLField('value', 'bans'), new OTS_SQLField('id', 'players') );
// selects only active bans
$actives = new OTS_SQLFilter();
$actives->addFilter( new OTS_SQLField('expires', 'bans'), 0);
$actives->addFilter( new OTS_SQLField('time', 'bans'), time(), OTS_SQLFilter::OPERATOR_GREATER, OTS_SQLFilter::CRITERIUM_OR);
$filter->addFilter($actives);
// creates list and aplies filter
$list = new OTS_Players_List();
$list->setFilter($filter);
return $list;
}
/**
* @version 0.1.5
* @since 0.1.3
* @return OTS_Accounts_List Filtered list.
* @deprecated 0.1.5 Use OTS_AccountBans_List.
*/
public static function bannedAccounts()
{
// creates filter
$filter = new OTS_SQLFilter();
$filter->addFilter( new OTS_SQLField('type', 'bans'), POT::BAN_ACCOUNT);
$filter->addFilter( new OTS_SQLField('active', 'bans'), 1);
$filter->addFilter( new OTS_SQLField('value', 'bans'), new OTS_SQLField('id', 'accounts') );
// selects only active bans
$actives = new OTS_SQLFilter();
$actives->addFilter( new OTS_SQLField('expires', 'bans'), 0);
$actives->addFilter( new OTS_SQLField('time', 'bans'), time(), OTS_SQLFilter::OPERATOR_GREATER, OTS_SQLFilter::CRITERIUM_OR);
$filter->addFilter($actives);
// creates list and aplies filter
$list = new OTS_Accounts_List();
$list->setFilter($filter);
return $list;
}
}
/**#@-*/
?>

View File

@@ -0,0 +1,224 @@
<?php
/**#@+
* @version 0.1.0
* @since 0.1.0
*/
/**
* @package POT
* @version 0.1.3
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 - 2008 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
*/
/**
* Wrapper for vocations.xml file.
*
* @package POT
* @version 0.1.3
* @example examples/vocations.php vocations.php
* @tutorial POT/data_directory.pkg#vocations
*/
class OTS_VocationsList implements IteratorAggregate, Countable, ArrayAccess
{
/**
* List of vocations.
*
* @var array
*/
private $vocations = array();
/**
* Loads vocations list from given file.
*
* @param string $file vocations.xml file location.
* @throws DOMException On DOM operation error.
*/
public function __construct($file)
{
// loads DOM document
$vocations = new DOMDocument();
$vocations->load($file);
// loads vocations
foreach( $vocations->getElementsByTagName('vocation') as $vocation)
{
$this->vocations[ (int) $vocation->getAttribute('id') ] = $vocation->getAttribute('name');
}
}
/**
* Magic PHP5 method.
*
* <p>
* Allows object importing from {@link http://www.php.net/manual/en/function.var-export.php var_export()}.
* </p>
*
* @param array $properties List of object properties.
* @throws DOMException On DOM operation error.
*/
public function __set_state($properties)
{
$object = new self();
// loads properties
foreach($properties as $name => $value)
{
$object->$name = $value;
}
return $object;
}
/**
* Checks if given vocation ID exists on list.
*
* @version 0.1.3
* @since 0.1.3
* @param int $id ID.
* @return bool If vocation is set then true.
*/
public function hasVocationId($id)
{
return isset($this->vocations[$id]);
}
/**
* Returns vocation's ID.
*
* @version 0.1.3
* @param string $name Vocation.
* @return int ID.
* @throws OutOfBoundsException If not found.
*/
public function getVocationId($name)
{
$id = array_search($name, $this->vocations);
// checks if vocation was found
if($id === false)
{
throw new OutOfBoundsException();
}
return $id;
}
/**
* Checks if given vocation name exists on list.
*
* @version 0.1.3
* @since 0.1.3
* @param string $name Vocation.
* @return bool If vocation is set then true.
*/
public function hasVocationName($name)
{
return array_search($name, $this->vocations) !== false;
}
/**
* Returns name of given vocation's ID.
*
* @version 0.1.3
* @param int $id Vocation ID.
* @return string Name.
* @throws OutOfBoundsException If not found.
*/
public function getVocationName($id)
{
if( isset($this->vocations[$id]) )
{
return $this->vocations[$id];
}
throw new OutOfBoundsException();
}
/**
* Returns amount of vocations loaded.
*
* @return int Count of vocations.
*/
public function count()
{
return count($this->vocations);
}
/**
* Returns iterator handle for loops.
*
* @return ArrayIterator Vocations list iterator.
*/
public function getIterator()
{
return new ArrayIterator($this->vocations);
}
/**
* Checks if given element exists.
*
* @version 0.1.3
* @param string|int $offset Array key.
* @return bool True if it's set.
*/
public function offsetExists($offset)
{
// integer key
if( is_int($offset) )
{
return isset($this->vocations[$offset]);
}
// vocation name
return array_search($offset, $this->vocations) !== false;
}
/**
* Returns item from given position.
*
* @version 0.1.3
* @param string|int $offset Array key.
* @return string|int If key is an integer (type-sensitive!) then returns vocation name. If it's a string then return associated ID.
*/
public function offsetGet($offset)
{
// integer key
if( is_int($offset) )
{
return $this->getVocationName($offset);
}
// vocations name
return $this->getVocationId($offset);
}
/**
* This method is implemented for ArrayAccess interface. In fact you can't write/append to vocations list. Any call to this method will cause {@link E_OTS_ReadOnly E_OTS_ReadOnly} raise.
*
* @param string|int $offset Array key.
* @param mixed $value Field value.
* @throws E_OTS_ReadOnly Always - this class is read-only.
*/
public function offsetSet($offset, $value)
{
throw new E_OTS_ReadOnly();
}
/**
* This method is implemented for ArrayAccess interface. In fact you can't write/append to vocations list. Any call to this method will cause {@link E_OTS_ReadOnly E_OTS_ReadOnly} raise.
*
* @param string|int $offset Array key.
* @throws E_OTS_ReadOnly Always - this class is read-only.
*/
public function offsetUnset($offset)
{
throw new E_OTS_ReadOnly();
}
}
/**#@-*/
?>

View File

@@ -0,0 +1,155 @@
<?php
/**#@+
* @version 0.1.2
* @since 0.1.2
*/
/**
* @package POT
* @author Wrzasq <wrzasq@gmail.com>
* @author Jeroen Derks <jeroen@derks.it>
* @copyright 2007 - 2008 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
* @license http://www.php.net/license/2_02.txt PHP License, Version 2.02
*/
/**
* XTEA encryption/decryption mechanism.
*
* <p>
* This code bases in large part on Jeroen Derks'es Crypt_Xtea's source code.
* </p>
*
* @package POT
*/
class OTS_XTEA implements IOTS_Cipher
{
/**
* Encryption key.
*
* @var array
*/
private $key;
/**
* Initializes new encryption session.
*
* <p>
* Note: Your key must be exacly 128bit length (16 characters)! Class will not resize it for you.
* </p>
*
* @param string $key Encryption key to be used.
*/
public function __construct($key)
{
$this->key = array_values( unpack('V4', $key) );
}
/**
* Encrypt a string with XTEA algorithm.
*
* @param string $message Data to encrypt.
* @return string Encrypted message.
*/
public function encrypt($message)
{
// resize data to 32 bits
$n = strlen($message);
$message = pack('v', $n) . str_pad($message, $n - ($n - 2) % 4 + 4, chr(0) );
// convert data to long integers
$message = array_values( unpack('V*', $message) );
$length = count($message);
// converts to unsigned integers
foreach($message as $index => $result)
{
if($result < 0)
{
$message[$index] += 0xFFFFFFFF + 1;
}
}
// resizes to 64 bits
if($length % 2 == 1)
{
$message[] = 0;
}
$result = '';
// encrypt the long data with the key
for($i = 0; $i < $length; $i++)
{
$sum = 0;
$delta = 0x9E3779B9;
$y = $message[$i];
$z = $message[++$i];
for($j = 0; $j < 32; $j++)
{
$y = OTS_BinaryTools::unsignedAdd($y, OTS_BinaryTools::unsignedAdd( ($z << 4) ^ OTS_BinaryTools::unsignedRightShift($z, 5), $z) ^ OTS_BinaryTools::unsignedAdd($sum, $this->key[$sum & 3]) );
$sum = OTS_BinaryTools::unsignedAdd($sum, $delta);
$z = OTS_BinaryTools::unsignedAdd($z, OTS_BinaryTools::unsignedAdd( ($y << 4) ^ OTS_BinaryTools::unsignedRightShift($y, 5), $y) ^ OTS_BinaryTools::unsignedAdd($sum, $this->key[ OTS_BinaryTools::unsignedRightShift($sum, 11) & 3]) );
}
// append the enciphered longs to the result
$result .= pack('VV', $y, $z);
}
return $result;
}
/**
* Decrypt XTEA-encrypted string.
*
* @param string $message Encrypted message.
* @return string Decrypted string.
*/
public function decrypt($message)
{
// convert data to long
$message = array_values( unpack('V*', $message) );
$length = count($message);
// converts to unsigned integers
foreach($message as $index => $result)
{
if($result < 0)
{
$message[$index] += 0xFFFFFFFF + 1;
}
}
// decrypt the long data with the key
$result = '';
for($i = 0; $i < $length; $i++)
{
$sum = 0xC6EF3720;
$delta = 0x61C88647;
$y = $message[$i];
$z = $message[++$i];
for($j = 0; $j < 32; $j++)
{
$z = OTS_BinaryTools::unsignedAdd($z, -( OTS_BinaryTools::unsignedAdd( ($y << 4) ^ OTS_BinaryTools::unsignedRightShift($y, 5), $y) ^ OTS_BinaryTools::unsignedAdd($sum, $this->key[ OTS_BinaryTools::unsignedRightShift($sum, 11) & 3]) ) );
$sum = OTS_BinaryTools::unsignedAdd($sum, $delta);
$y = OTS_BinaryTools::unsignedAdd($y, -( OTS_BinaryTools::unsignedAdd( ($z << 4) ^ OTS_BinaryTools::unsignedRightShift($z, 5), $z) ^ OTS_BinaryTools::unsignedAdd($sum, $this->key[$sum & 3]) ) );
}
// append the deciphered longs to the result data
$result .= pack('VV', $y, $z);
}
// reads message length
$offset = unpack('v', $result);
return substr($result, 2, $offset[1]);
}
}
/**#@-*/
?>

77
system/libs/pot/README Normal file
View File

@@ -0,0 +1,77 @@
POT (PHP OTServ Toolkit) is a PHP toolkit for scripts that work with OTServ database.
===== About =====
This toolkit provides a way for PHP programmers that don't know SQL langauge to work with OTServ database.
For installation help check INSTALL file.
For usage tutorial/API documentation check http://otserv-aac.info/ or documentation.pdf file.
===== Contact =====
In case of any contact needed, please use following e-mail address: wrzasq@gmail.com.
===== Files =====
classes/ - POT class files.
examples/ - example files for learning.
tutorials/ - phpDocumentor directory.
CHANGELOG - changes history.
INSTALL - installation tutorial.
LICENSE - POT license (GNU LGPL v3), if you don't accept it - don't use any of those scripts.
LICENSE.PEAR.CRYPT_RSA - PEAR::Crypt_RSA (PHP License, version 3.0), if you don't accept it - don't use any of those scripts.
LICENSE.PEAR.CRYPT_XTEA - PEAR::Crypt_XTEA (PHP License, version 2.02), if you don't accept it - don't use any of those scripts.
NEWS - changes in current release.
README - this readme file.
RULES - rules to be followed during developing contributed code.
Makefile - make input, for documentation generation.
POT.psf - PHK Package Specification File.
documentation.pdf - phpDocumentor-generater documentation in PDF format.
compat.php - compatibility assurance library.
phar.php - PHAR package build script.
test.php - phpUnit test suite.
===== Makefile =====
Makefile contains some targets for make that can help in development. Makefile requires following command-line commands:
php: PHP CLI interface.
phpdoc: phpDocumentor.
phpunit: PHPUnit testing framework.
PHK_Creator.phk: this is file which you download from http://phk.tekwire.net/.
To build PHAR package you will need PECL PHAR extension installed.
Possible targets:
all: default one, runs all other targets (in order: clean, check, documentation, pdf, online, test, package, manual, phk, phar).
clean: deletes documentation.
check: checks syntax of all PHP files.
documentation: generates HTML documentation.
pdf: generates PDF documentation.
online: OTServ-AAC website documentation template used.
test: runs test suite.
package: creates pot.tar.gz file for distribution purposes.
manual: creates documentation.tar.gz file for distribution purposes.
phk: creates POT.phk distribution package.
phar: creates POT.phar distribution package.
For more readable output of phpUnit test run:
php test.php
===== Credits =====
* Wrzasq <wrzasq@gmail.com> - project initiator, main developer.
For more info see AUTHORS file in OTServ tree.

68
system/libs/pot/RULES Normal file
View File

@@ -0,0 +1,68 @@
Zero rule: We use Unicode (UTF-8).
Of course we should handle input encoding respectively, but output and internal data/code are all written in UTF-8.
I. Coding rules to be followed:
[1] Never ever use global!
It's just the worst thing you can do in PHP scripts.
[2] Avoid using define - use class constants.
To group code better, to allow classes __autoload() handling.
[3] Use !isset() instead of is_null().
That has exacly same effect and we should follow the most simplies methods. Just to make code cleaner (however remember that isset() is a PHP langauge structure and has it's limitations!).
[4] Don't use functions - use class methods (except Compat package).
This will allow __autoload() handling for all routines as they will be members of classes.
[5] Use 4 spaces as tabulation.
Tabulator character can be differently displayed and generaly four spaces makes code more readable.
[6] Always use brackets for blocks and leave them in separated lines in same nesting level that block instruction:
if(condition)
{
for($i = 0; $i < $j; $i++)
{
statement;
}
}
[7] Use single quotes insead of double ones.
' are, in standard way, faster then " and it keeps code cleaner if you simply concat everything rather then inserting something like placeholders into string.
[8] Use spaces between parenthess and operators (except object member accessing operator):
$foo = $lol . $rotfl;
$foo .= $bar;
$obj = new Class( substr( str_replace( implode('.', $array), ',', '.'), 2) );
echo $obj->field;
echo $obj->method( rand() );
echo $obj->method($value);
[9] Use <?php opening tag.
It is the most reliable and standard way for starting PHP code.
[10] Use isset(array[offset]) instead of array_key_exists().
It saves alot of resources (relatively).
II. File naming:
[1] Use lowercase names for directories.
[2] Use fiels and directories in code in case-sensitive way.
Remember that probably this code will be mostly run on non-Windows platforms.
[3] Use existing directories structure.
Put classes into classes directory, tutorials into tutorials directory etc.

View File

@@ -0,0 +1,85 @@
<?php
/**#@+
* @version 0.0.2
* @since 0.0.2
*/
/**
* POT compatibility assurance package.
*
* This package makes you sure that POT scripts won't cause FATAL errors on PHP older PHP 5.x versions. However remember that some PHP features won't be enabled with it. For example if you have PHP 5.0.x, this package will define Countable interface for you so PHP will know it, but it won't allow you to use count($countableObject) structure.
*
* Note that you need to include this file before any other POT file or they will cause FATAL errors.
*
* @package POT
* @version 0.1.2
* @subpackage compat
* @author Wrzasq <wrzasq@gmail.com>
* @copyright 2007 - 2008 (C) by Wrzasq
* @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU Lesser General Public License, Version 3
* @tutorial POT/PHP_5.0.pkg
*/
// OutOfBoundsException class for 5.0.x
if( !class_exists('OutOfBoundsException') )
{
/**
* @ignore
* @version 0.1.0
* @since 0.1.0
*/
class OutOfBoundsException extends Exception
{
}
}
// LogicException class for 5.0.x
if( !class_exists('LogicException') )
{
/**
* @ignore
* @version 0.1.2
* @since 0.1.2
*/
class LogicException extends Exception
{
}
}
// Countable for PHP 5.0.x
if( !interface_exists('Countable') )
{
/**
* @ignore
*/
interface Countable
{
public function count();
}
}
// spl_autoload_register() walkaround
if( !function_exists('spl_autoload_register') )
{
/**
* @ignore
*/
function spl_autoload_register($callback)
{
if( !function_exists('__autoload') )
{
/**
* @ignore
*/
function __autoload($class)
{
POT::getInstance()->loadClass($class);
}
}
}
}
/**#@-*/
?>