Veteran Member
Join Date: Feb 2011
Location: Stockholm, Sweden
|
10-29-2014
, 12:50
Unfinished project: GUI Inventory
|
#1
|
An inventory system that works through MOTD.
Could be used for something like a DayZ mod. Most of the PHP and JavaScript code is done. The plugin is not.
Live presentation (You can only move things and send the commands, they don't do anything on the server now. If HLDS is down it will pause on commands.):
http://digitaldecay.eu/projects/inve...Drop&AuthKey=X
Movements on the webpage are sent directly to the database, commands to the server.
I will probably never finish this due to changes in my personal life.
I'm sharing it because it feels dumb to just sit on it without any purpose. So if you want to finish it or just browse the code for inspiration, do so freely.
Code:
#include <amxmodx>
new const KEY[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
new const URL[] = ""; // Location of the php file, for example: "http://divinityx.eu/projects/inventory"
enum PlayerInfoEnum {
_SteamID,
_AuthKey[5]
}
enum _:PluginInfoEnum {
_PluginID,
_hForward,
_TableName[32],
_SizeX,
_SizeY,
Array:_MenuOptions
}
new gPlayerInfo[33][PlayerInfoEnum];
new Array:gPluginInfo;
new gPluginInfoSize;
new gMaxPlayers;
public plugin_natives() {
gPluginInfo = ArrayCreate(PluginInfoEnum, 1);
register_native("RegisterInventory", "native_Register");
//register_native("InventoryHasRoomFor", "native_HasRoomFor");
//register_native("InventoryAddItem", "native_AddItem");
//register_native("InventoryRemoveItem", "native_RemoveItem");
//register_native("InventoryGetItemQuantity", "native_GetItemQuantity");
//register_native("InventorySetItemQuantity", "native_SetItemQuantity");
//register_native("InventoryGetUserItems", "native_GetUserItems");
register_native("InventoryDisplay", "native_Display");
}
/* TableName, X, Y */
public native_Register(PluginID) {
static PluginInfo[PluginInfoEnum];
PluginInfo[_PluginID] = PluginID;
get_string(1, PluginInfo[_TableName], charsmax(PluginInfo[_TableName]));
PluginInfo[_SizeX] = clamp(get_param(2), 1, 32);
PluginInfo[_SizeY] = clamp(get_param(3), 1, 128);
ArrayPushArray(gPluginInfo, PluginInfo);
gPluginInfoSize++;
}
/* id */
public native_Display(PluginID, numParams) {
new id = get_param(1);
static PluginInfo[PluginInfoEnum];
if ( GetInventoryInfo(PluginID, PluginInfo) == -1 )
return;
static MOTD[256];
formatex(MOTD, charsmax(MOTD), "%s?Table=inventory&X=%d&Y=%d&Size=%d&SteamID=%d&AuthKey=%s", URL, PluginInfo[_TableName], PluginInfo[_SizeX], PluginInfo[_SizeY], gPlayerInfo[id][_SteamID], gPlayerInfo[id][_AuthKey]);
new size = ArraySize(PluginInfo[_MenuOptions]);
static TempString[32];
TempString[0] = ',';
for ( new i ; i < size ; i++ ) {
ArrayGetString(PluginInfo[_MenuOptions], i, TempString[1], charsmax(TempString) - 1);
add(MOTD, charsmax(MOTD), TempString);
}
show_motd(id, MOTD, "Inventory");
}
GetInventoryInfo(PluginID, PluginInfo[]) {
for ( new i = 0 ; i < gPluginInfoSize ; i++ ) {
ArrayGetArray(gPluginInfo, i, PluginInfo);
if ( PluginID == PluginInfo[_PluginID] )
return PluginID;
}
return -1;
}
public plugin_init() {
register_plugin("GUI Inventory API", "1.0", "[ --{-@ ]");
gMaxPlayers = get_maxplayers();
register_srvcmd("_InventoryCommand", "InventoryCommand");
}
public client_authorized(id) {
static SteamID[21];
get_user_authid(id, SteamID, charsmax(SteamID));
gPlayerInfo[id][_SteamID] = iSteamID(SteamID);
for ( new i ; i < sizeof gPlayerInfo[][_AuthKey] - 1 ; i++ )
gPlayerInfo[id][_AuthKey][i] = KEY[random(sizeof KEY)];
}
public client_disconnect(id)
gPlayerInfo[id][_SteamID] = 0;
public InventoryCommand() {
static Command[32];
static SteamID[21];
static ItemIndex[12];
static AuthKey[5];
read_argv(1, SteamID, charsmax(SteamID));
read_argv(2, AuthKey, charsmax(AuthKey));
read_argv(3, ItemIndex, charsmax(ItemIndex));
read_argv(4, Command, charsmax(Command));
new iItemIndex = str_to_num(ItemIndex);
new iSteamID = str_to_num(SteamID);
new id = GetPlayer(iSteamID);
if ( ! id )
return;
if ( ! equal(AuthKey, gPlayerInfo[id][_AuthKey]) )
return;
server_print("Inventory command %s was called by %d for item %d", Command, id, iItemIndex);
// static r;
// server_print("%d", r++); // This is the response to the webpage, it will determine an action of the object ( remove, increase, decrease ) depending on what the plugin tells it to do.
}
GetPlayer(iSteamID) {
for ( new i = 1 ; i < gMaxPlayers ; i++ ) {
if ( gPlayerInfo[i][_SteamID] && iSteamID == gPlayerInfo[i][_SteamID] )
return i;
}
return 0;
}
iSteamID(SteamID[])
return str_to_num(SteamID[10]) | '0' - SteamID[8] << 31;
PHP Code:
<?php
/*
drop table inventory;
create table if not exists inventory ( ItemIndex int primary key auto_increment, SteamID int, Quantity int, PosX tinyint unsigned, PosY tinyint unsigned, SizeX tinyint unsigned, SizeY tinyint unsigned, Image varchar(256), Description varchar(8192) );
insert into inventory ( SteamID, Quantity, PosX, PosY, SizeX, SizeY, Image, Description) values( -2127214489, -1, 0, 0, 2, 3, 'img/sword.png', '<font color=#8888FF><b>Death Needle</b><br>One-handed short sword</font><br><br>Damage: 8 to 13<br>Required Strenght: 21<br>Required Level: 5<br><br><font color=#8888FF>+20% Attack Speed<br></font>' );
insert into inventory ( SteamID, Quantity, PosX, PosY, SizeX, SizeY, Image, Description) values( -2127214489, -1, 0, 3, 2, 3, 'img/bow.png', '<font color=#DDDD00><b>Heaven\\''s Blessing</b><br>Two-handed longbow</font><br><br>Damage: <font color=#8888FF>35</font> to <font color=#8888FF>42</font><br>Required Dexterity: 89<br>Required Level: 25<br><br><font color=#8888FF>+50% Increased Damage<br></font>' );
insert into inventory ( SteamID, Quantity, PosX, PosY, SizeX, SizeY, Image, Description) values( -2127214489, -1, 2, 0, 2, 2, 'img/helm.png', '<b>Viking Helmet</b><br><br>Defense: 4' );
insert into inventory ( SteamID, Quantity, PosX, PosY, SizeX, SizeY, Image, Description) values( -2127214489, 7, 2, 2, 1, 1, 'img/taco.png', '<b>Taco</b><br>Regenerates 3 hunger.' );
insert into inventory ( SteamID, Quantity, PosX, PosY, SizeX, SizeY, Image, Description) values( -2127214489, -1, 8, 2, 8, 4, 'img/nuke.png', '<font color=#FFFF44><b>BIG-ASS FUCKING NUKE!<br><br>Blast everyone to nirvana and back!</b></font>' );
*/
/* SETTINGS */
$SQL["TYPE"] = "mysql";
$SQL["HOST"] = "127.0.0.1";
$SQL["USER"] = "root";
$SQL["PASS"] = "";
$SQL["DB"] = "amxx";
$SRV["IP"] = "127.0.0.1"; // Don't use localhost.
$SRV["PORT"] = 27015;
$SRV["RCON"] = "";
$SRV["TIMEOUT"] = 100000;
/* END OF SETTINGS */
if ( isset($_GET["Table"]) )
$SQL["TABLE"] = $_GET["Table"];
if ( isset($_GET["Func"]) ) {
/* Thank you xPaw for SourceQuery, which this part is more or less ripped from. */
$hSocket = @fsockopen("udp://" . $SRV["IP"], $SRV["PORT"], $ErrNo, $ErrStr, ( $SRV["TIMEOUT"] / 1000000 ));
if ( $hSocket === false )
return;
Stream_Set_Timeout($hSocket, 0, $SRV["TIMEOUT"]);
Stream_Set_Blocking($hSocket, true);
fwrite($hSocket, "\xFF\xFF\xFF\xFFchallenge rcon", 18);
$Buffer = "";
while ( ! $Buffer )
$Buffer = fread($hSocket, 1400);
$Command = "\xFF\xFF\xFF\xFFrcon " . trim(substr($Buffer, 19)) . " \"" . $SRV["RCON"] . "\" ";
if ( $_GET["Func"] == 1 )
$Command .= "_InventoryCommand \"" . $_GET["SteamID"] . "\" \"" . $_GET["AuthKey"] . "\" \"" . $_GET["ItemIndex"] . "\" \"" . $_GET["Command"] . "\"";
$Length = StrLen($Command);
FWrite( $hSocket, $Command, $Length );
$Buffer = "";
while ( ! $Buffer )
$Buffer = fread($hSocket, 1400);
echo substr($Buffer, 5);
fclose($hSocket);
return;
}
else if ( isset($_GET["ItemIndex"]) ) {
$hDB = new PDO($SQL["TYPE"] . ":host=" . $SQL["HOST"] . ";dbname=" . $SQL["DB"] . "", $SQL["USER"], $SQL["PASS"]);
if ( $hDB === false )
return;
$hQuery = $hDB->prepare("update " . $SQL["TABLE"] . " set PosX = " . $_GET["X"] . ", PosY = " . $_GET["Y"] . " where ItemIndex = " . $_GET["ItemIndex"] . ";");
$hQuery->execute();
return;
}
?>
<html>
<link rel=stylesheet type=text/css href=index.css>
<?php
$SlotSize = $_GET["Size"];
$ReserveSlots = "";
echo "<div id=OuterBorder onblur=\"WindowClose()\">";
echo "<div id=InvBorder style=\"";
if ( isset($_GET["bgimg"]) )
echo " background-image: url('". $_GET["bgimg"] . "');";
else if ( isset($_GET["bgcol"]) )
echo " background-color: #" . $_GET["bgcol"] . ";";
else
echo "";
echo "\">";
for ( $Y = 0 ; $Y < $_GET["Y"] ; $Y++ ) {
for ( $X = 0 ; $X < $_GET["X"] ; $X++ )
echo "<div class=InvFrame id=\"" . $X . "x" . $Y . "\" style=\"width: " . ( $SlotSize - 2 ) . "px; height: " . ( $SlotSize - 2 ) . "px;\"></div>";
echo "<br>";
}
$hDB = new PDO($SQL["TYPE"] . ":host=" . $SQL["HOST"] . ";dbname=" . $SQL["DB"] . "", $SQL["USER"], $SQL["PASS"]);
$hQuery = $hDB->prepare("select * from " . $SQL["TABLE"] . " where SteamID = " . $_GET["SteamID"] . ";");
$hQuery->execute();
while ( $hResult = $hQuery->fetch(PDO::FETCH_OBJ) ) {
$ReserveSlots .= "ReserveSlot(" . $hResult->PosX . ", " . $hResult->PosY . ", " . $hResult->SizeX . ", " . $hResult->SizeY . ");";
echo "<div class=Item onmouseout=MouseOut() onmouseover=\"MouseOver(this,'" . $hResult->Description . "')\" onmousedown=\"MouseDown(this, " . $hResult->ItemIndex . ", " . $hResult->SizeX . ", " . $hResult->SizeY . ")\" onmouseup=MouseUp() style=\"background: url(bg-grey.png); left: " . $hResult->PosX * $SlotSize . "; top: " . $hResult->PosY * $SlotSize . "; width: " . $hResult->SizeX * $SlotSize . "px; height: " . $hResult->SizeY * $SlotSize . "px;\"><div class=ItemCover><div class=ItemQuantity>" . ( $hResult->Quantity == -1 ? "" : $hResult->Quantity ) . "</div></div><img src=\"" . $hResult->Image . "\" class=ItemImage></div>";
}
echo "</div>"; // InvBorder
echo "<div id=DescriptionBox></div>";
echo "<div id=Menu>";
$MenuItems = explode(",", $_GET["Menu"]);
foreach ($MenuItems as &$MenuItem) {
echo "<div onmousedown=\"SendMenuItem('" . $MenuItem . "')\" class=MenuItem>" . $MenuItem . "</div>";
}
echo "</div>"; // Menu
echo "</div>"; // OuterBorder
?>
<script>
<?php
echo "
var gInvSize = [" . $_GET["X"] . ", " . $_GET["Y"] . "];
var gSlotSize = " . $SlotSize . ";
var gSteamID = " . $_GET["SteamID"] . ";
";
?>
var gItemIndex;
var gPickUpOffset = [0, 0];
var gPickUpPos = [0, 0];
var gMousePos = [0, 0];
var gSlot = [0, 0];
var gItemSize = [0, 0];
var gPickedUpObject;
var gCanPlace;
var ggIsClick = false;
var gDescBox = document.getElementById("DescriptionBox");
var gDescBoxPos = [0, 0];
var gMenu = document.getElementById("Menu");
var gMenuItem;
var gMenuObject;
function ReserveSlot(PosX, PosY, SizeX, SizeY) {
for ( var X = 0 ; X < SizeX ; X++ ) {
for ( var Y = 0 ; Y < SizeY ; Y++ ) {
if ( 0 <= PosX + X && PosX + X < gInvSize[0] && 0 <= PosY + Y && PosY + Y < gInvSize[1] )
document.getElementById( ( PosX + X ) + "x" + ( PosY + Y ) ).style.fontsize = 1;
}
}
}
function ReleaseSlot(PosX, PosY, SizeX, SizeY) {
for ( var X = 0 ; X < SizeX ; X++ ) {
for ( var Y = 0 ; Y < SizeY ; Y++ ) {
if ( 0 <= PosX + X && PosX + X < gInvSize[0] && 0 <= PosY + Y && PosY + Y < gInvSize[1] )
document.getElementById( ( PosX + X ) + "x" + ( PosY + Y ) ).style.fontsize = 0;
}
}
}
function PaintBackground(PosX, PosY, SizeX, SizeY, Color) {
for ( var X = 0 ; X < SizeX ; X++ ) {
for ( var Y = 0 ; Y < SizeY ; Y++ ) {
if ( 0 <= PosX + X && PosX + X < gInvSize[0] && 0 <= PosY + Y && PosY + Y < gInvSize[1] )
document.getElementById( ( PosX + X ) + "x" + ( PosY + Y ) ).style.background = Color;
}
}
}
function MouseOver(Object, Description) {
if ( ! gMenuItem ) {
gDescBox.innerHTML = Description;
gDescBox.style.visibility = "visible";
}
}
function MouseOut() {
gDescBox.innerHTML = "";
gDescBox.style.visibility = "hidden";
}
function MouseDown(Object, ItemIndex, SizeX, SizeY) {
gIsClick = true;
setTimeout("ClickTimer()", 200)
var X = parseInt(Object.style.left);
var Y = parseInt(Object.style.top);
gPickUpOffset[0] = ( gMousePos[0] - X );
gPickUpOffset[1] = ( gMousePos[1] - Y );
gPickUpPos[0] = X / gSlotSize;
gPickUpPos[1] = Y / gSlotSize;
gItemSize[0] = SizeX;
gItemSize[1] = SizeY;
ReleaseSlot(gPickUpPos[0], gPickUpPos[1], SizeX, SizeY);
gCanPlace = false;
Object.style.background = "";
PaintBackground(gPickUpPos[0], gPickUpPos[1], SizeX, SizeY, "url(bg-green.png)");
gItemIndex = ItemIndex;
gPickedUpObject = Object;
}
function ClickTimer() {
gIsClick = false;
}
function MouseUp() {
if ( ! gPickedUpObject )
return;
if ( ! gCanPlace || ( gPickUpPos[0] == gSlot[0] && gPickUpPos[1] == gSlot[1] ) ) {
gPickedUpObject.style.left = gPickUpPos[0] * gSlotSize + "px";
gPickedUpObject.style.top = gPickUpPos[1] * gSlotSize + "px";
ReserveSlot(gPickUpPos[0], gPickUpPos[1], gItemSize[0], gItemSize[1]);
}
else {
gPickedUpObject.style.left = gSlot[0] * gSlotSize + "px";
gPickedUpObject.style.top = gSlot[1] * gSlotSize + "px";
ReserveSlot(gSlot[0], gSlot[1], gItemSize[0], gItemSize[1]);
MoveObject(gItemIndex, gSlot[0], gSlot[1]);
}
if ( gIsClick ) {
var TempSize = parseInt(gPickedUpObject.style.width);
if ( TempSize < gSlotSize * 2 )
TempSize = gSlotSize * 2;
gMenu.style.width = TempSize;
gMenu.style.left = gPickedUpObject.style.left;
gMenu.style.top = gPickedUpObject.style.top;
gMenu.style.visibility = 'visible';
gMenuItem = gItemIndex;
gMenuObject = gPickedUpObject;
MouseOut();
}
gPickedUpObject.style.background = "url(bg-grey.png)"
gPickedUpObject = 0;
gItemIndex = 0;
for ( var X = 0 ; X < gInvSize[0] ; X++ ) {
for ( var Y = 0 ; Y < gInvSize[1] ; Y++ ) {
document.getElementById( X + "x" + Y ).style.background = "";
}
}
}
function MouseMove(Event) {
gMousePos[0] = Event.pageX
gMousePos[1] = Event.pageY
gDescBoxPos[0] = gMousePos[0] + 10
gDescBoxPos[1] = gMousePos[1] - 50
if ( gDescBoxPos[1] < 0 )
gDescBoxPos[1] = 0;
if ( gDescBoxPos[0] < 0 )
gDescBoxPos[0] = 0;
gDescBox.style.left = gDescBoxPos[0] + "px";
gDescBox.style.top = gDescBoxPos[1] + "px";
if ( gPickedUpObject ) {
var Pos = [0,0];
Pos[0] = gMousePos[0] - gPickUpOffset[0];
Pos[1] = gMousePos[1] - gPickUpOffset[1];
gPickedUpObject.style.left = Pos[0] + "px";
gPickedUpObject.style.top = Pos[1] + "px";
gSlot[0] = Math.floor( ( Pos[0] + gSlotSize / 2 ) / gSlotSize );
gSlot[1] = Math.floor( ( Pos[1] + gSlotSize / 2 ) / gSlotSize );
gCanPlace = true;
for ( var X = 0 ; X < gItemSize[0] ; X++ ) {
for ( var Y = 0 ; Y < gItemSize[1] ; Y++ ) {
if ( gSlot[0] < 0 || gSlot[1] < 0 || ( gSlot[0] + X ) >= gInvSize[0] || ( gSlot[1] + Y ) >= gInvSize[1] || document.getElementById( ( gSlot[0] + X ) + "x" + ( gSlot[1] + Y ) ).style.fontsize == 1 ) {
gCanPlace = false;
break;
}
}
}
for ( var X = 0 ; X < gInvSize[0] ; X++ ) {
for ( var Y = 0 ; Y < gInvSize[1] ; Y++ ) {
document.getElementById( X + "x" + Y ).style.background = "";
}
}
PaintBackground(gSlot[0], gSlot[1], gItemSize[0], gItemSize[1], gCanPlace ? "url(bg-green.png)" : "url(bg-red.png)");
}
return true
}
function MoveObject(ItemIndex, PosX, PosY) {
SendRequest("?ItemIndex=" + ItemIndex + "&X=" + PosX + "&Y=" + PosY + "&Table=<?php echo $_GET["Table"] ?>");
}
function eMouseDown(Event) {
if ( gMenuItem ) {
document.getElementById("Menu").style.visibility = 'hidden';
gMenuItem = 0;
}
}
function SendMenuItem(MenuItemName) {
var Response = SendRequest("?Func=1&SteamID=" + gSteamID + "&AuthKey=<?php echo $_GET["AuthKey"]?>" + "&ItemIndex=" + gMenuItem + "&Command=" + MenuItemName);
if ( Response & 1 ) { // Remove
gMenuObject.style.visibility = 'hidden';
ReleaseSlot(gPickUpPos[0], gPickUpPos[1], gItemSize[0], gItemSize[1]);
}
if ( Response & 2 ) { // Decrease
}
if ( Response & 4 ) { // Increase
}
}
function SendRequest(Request) {
var xmlHttp = null;
xmlHttp = new XMLHttpRequest();
xmlHttp.open("GET", Request, false);
xmlHttp.send(null);
return parseInt(xmlHttp.responseText);
}
document.onmousemove = MouseMove;
document.onmousedown = eMouseDown;
<?php
echo $ReserveSlots;
?>
</script>
</html>
__________________
Last edited by Black Rose; 07-09-2017 at 15:39.
|
|