Raised This Month: $32 Target: $400
 8% 

Unfinished project: GUI Inventory


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
Black Rose
Veteran Member
Join Date: Feb 2011
Location: Stockholm, Sweden
Old 10-29-2014 , 12:50   Unfinished project: GUI Inventory
Reply With Quote #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($hSocket0$SRV["TIMEOUT"]);
    
Stream_Set_Blocking($hSockettrue);
    
    
fwrite($hSocket"\xFF\xFF\xFF\xFFchallenge rcon"18);
    
    
$Buffer "";
    
    while ( ! 
$Buffer )
        
$Buffer fread($hSocket1400);

    
$Command "\xFF\xFF\xFF\xFFrcon " trim(substr($Buffer19)) . " \"" $SRV["RCON"] . "\" ";

    if ( 
$_GET["Func"] == )
        
$Command .= "_InventoryCommand \"" $_GET["SteamID"] . "\" \"" $_GET["AuthKey"] . "\" \"" $_GET["ItemIndex"] . "\" \"" $_GET["Command"] . "\"";
    
    
$Length StrLen($Command);
    
FWrite$hSocket$Command$Length );
    
    
$Buffer "";
    
    while ( ! 
$Buffer )
        
$Buffer fread($hSocket1400);
    
    echo 
substr($Buffer5);

    
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 $Y $_GET["Y"] ; $Y++ ) {
    for ( 
$X $X $_GET["X"] ; $X++ )
        echo 
"<div class=InvFrame id=\"" $X "x" $Y "\" style=\"width: "  . ( $SlotSize ) .  "px; height: " . ( $SlotSize ) . "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 == -"" $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.
Black Rose is offline
Kia
AlliedModders Donor
Join Date: Apr 2010
Location: In a world of madness
Old 10-30-2014 , 02:43   Re: Unfinished project: GUI Inventory
Reply With Quote #2

Looks sexy, thanks for sharing.
__________________
Kia is offline
klippy
AlliedModders Donor
Join Date: May 2013
Location: Serbia
Old 10-30-2014 , 05:29   Re: Unfinished project: GUI Inventory
Reply With Quote #3

I thought that JavaScript is not implemented in MOTD. Now, I am wondering again... is it?
By the way, awesome work!
klippy is offline
Roccoxx
AlliedModders Donor
Join Date: Jan 2012
Location: Argentina
Old 11-23-2014 , 10:16   Re: Unfinished project: GUI Inventory
Reply With Quote #4

wow nice! i wait for more changes (Y)
__________________
Tutorials here (Spanish)

Like as another Pijudo said: "Tired and retired"
Roccoxx is offline
Send a message via MSN to Roccoxx
Netsys
Senior Member
Join Date: Feb 2010
Old 12-04-2014 , 08:54   Re: Unfinished project: GUI Inventory
Reply With Quote #5

The web doesn't work, but looks nice!
Netsys is offline
Black Rose
Veteran Member
Join Date: Feb 2011
Location: Stockholm, Sweden
Old 12-08-2014 , 12:24   Re: Unfinished project: GUI Inventory
Reply With Quote #6

The server is down. Sorry. A fuse blew at home. I will fix it whenever I'm home the next time. Around christmas at worst.
Also the HLDS is crashing now and then for some reason i don't know (not related to this project) so the website behaves kind of weird. You get the general idea.
__________________
Black Rose is offline
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 04:06.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode