logo logo

 Back to main page

The NWNX Community Forum

 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 
 
list of players on two servers --- noob

 
Post new topic   Reply to topic    nwnx.org Forum Index -> Scripts and Modules
View previous topic :: View next topic  
Author Message
Pwyll



Joined: 27 Apr 2007
Posts: 1

PostPosted: Fri Apr 27, 2007 19:02    Post subject: list of players on two servers --- noob Reply with quote

Hi

I'm noob in using NWNX and would like to know if there is any tool that would let you see toon names or player log-ins on another server that shares a toon vault.

background..

the mod grow to a size that it had to be split to two servers. Needless to say the players and DMs would find it very useful to be able to see who is on the other server when they are in the game.
Back to top
View user's profile Send private message
Papillon
x-man


Joined: 28 Dec 2004
Posts: 1060
Location: Germany

PostPosted: Fri Apr 27, 2007 22:57    Post subject: Reply with quote

You should be able to find something like this on nwvault.ign.com. If you have a webserver that can access your MySQL database, you can have a script (e.g. written in PHP) that displays the logged in players, and have that list updated in the database everytime someone logs on or off.
_________________
Papillon
Back to top
View user's profile Send private message Visit poster's website MSN Messenger
Grumalg



Joined: 04 Nov 2005
Posts: 70

PostPosted: Fri Apr 27, 2007 23:08    Post subject: Reply with quote

It certainly can and has been done before. What you mention splits into two seperate things. First, reflecting a login to another server, and second being able to display a list of players online on both servers.

To show login events on another server create a custom table that holds only such event records. When an event occurs, insert a record into this table holding the information to display on other server and which server it's intended for. Each server then polls this table via heartbeat and if it finds record(s) intended for it, it displays the information and deletes the record(s). You can reduce the DB loading in the heartbeat by doing such checks every n heartbeats if you're willing to have response time be slow. This approach can also be used to implement inter-server messageing such as 'tells' between players on different servers.

Displaying a list of players on both servers requires another custom table. This table holds either a list of every player with a 'online' flag in it showing who's online now, or can hold only one record for each player online on either server. In either case when the list is invoked you fetch the set of records of online players and loop through the records displaying the list.

Both of these techniques are expandable to handle more than two servers.

--- Grumalg ---
Back to top
View user's profile Send private message
FunkySwerve



Joined: 02 Jun 2005
Posts: 377

PostPosted: Sat Apr 28, 2007 23:38    Post subject: Reply with quote

Here's a script to do this, though you'd have to modify it for your servers:

Code:
#include "aps_include"

void main()
{
    object oPC = GetPCSpeaker();
    string sServer1List, sServer2List, sServer3List, sServer4List, sServer5List, sServer6List, sS1Header, sS2Header, sS3Header, sS4Header, sS5Header, sS6Header;
    string sMessage, sPCName, sCharName, sLevel, sListServer;
    string sServer = GetLocalString(GetModule(), "ServerNumber");
    string SQL;
    int nCount;
    SQL = "SELECT pcname, charname, level, server FROM loggedin " + /*WHERE server<>'"+ sServer +"' */ "ORDER BY level";
    sMessage = "<c2>You are on server </c><c>216.144.214."+ sServer +"</c><c2>. Here are the players currently online:</c>\n<c2>Key: L = Level, P = Player, C = Character</c>\n";
    SQLExecDirect(SQL);
    while(SQLFetch() != SQL_ERROR) //lists 112 and 113
    {
        sPCName = SQLDecodeSpecialChars(SQLGetData(1));
        sCharName = SQLDecodeSpecialChars(SQLGetData(2));
        sLevel = SQLGetData(3);
        sListServer = SQLGetData(4);
        if (sListServer == "111") sServer1List += "<c>L: </c><c >" + sLevel + "</c><c>, P: </c><c>" + sPCName + "</c><c>, C: </c><c>" + sCharName + "</c>\n";
        else if (sListServer == "112") sServer2List += "<c>L: </c><c >" + sLevel + "</c><c>, P: </c><c>" + sPCName + "</c><c>, C: </c><c>" + sCharName + "</c>\n";
        else if (sListServer == "113") sServer3List += "<c>L: </c><c >" + sLevel + "</c><c>, P: </c><c>" + sPCName + "</c><c>, C: </c><c>" + sCharName + "</c>\n";
        else if (sListServer == "114") sServer4List += "<c>L: </c><c >" + sLevel + "</c><c>, P: </c><c>" + sPCName + "</c><c>, C: </c><c>" + sCharName + "</c>\n";
        else if (sListServer == "115") sServer5List += "<c>L: </c><c >" + sLevel + "</c><c>, P: </c><c>" + sPCName + "</c><c>, C: </c><c>" + sCharName + "</c>\n";
        else sServer6List += "<c>L: </c><c >" + sLevel + "</c><c>, P: </c><c>" + sPCName + "</c><c>, C: </c><c>" + sCharName + "</c>\n";
        nCount++;
    }
    if (sServer1List != "") sS1Header = "<c2>=====Server 111=====</c>\n";
    if (sServer2List != "") sS2Header = "<c2>=====Server 112=====</c>\n";
    if (sServer3List != "") sS3Header = "<c2>=====Server 113=====</c>\n";
    if (sServer4List != "") sS4Header = "<c2>=====Server 114=====</c>\n";
    if (sServer5List != "") sS5Header = "<c2>=====Server 115=====</c>\n";
    if (sServer6List != "") sS6Header = "<c2>=====Server 116=====</c>\n";
    sMessage += sS1Header + sServer1List + sS2Header + sServer2List + sS3Header + sServer3List + sS4Header + sServer4List + sS5Header + sServer5List + sS6Header + sServer6List;
    sMessage += "<c2>There are " + IntToString(nCount) + " players online.</c>\n";
    sMessage += "<c2>You are on server </c><c>216.144.214."+ sServer +".</c>";
    SendMessageToPC(oPC, sMessage);
}


It uses this oncliententer:
Code:
#include "aps_include"
int MarkCharacterEntry(object oPlayer)
{
    int nBoot = FALSE;
    //object oPlayer = GetEnteringObject();
    string sServer;
    sServer = GetLocalString(OBJECT_SELF, "ServerNumber");//returns either 111 or 112
    string sPlayer;
    string sUnencoded = GetPCPlayerName(oPlayer);
    sPlayer = SQLEncodeSpecialChars(sUnencoded);
    string sName = SQLEncodeSpecialChars(GetName(oPlayer));
    int nLevel;
    nLevel = GetHitDice(oPlayer);
    int nLootable;
    nLootable = GetLootable(oPlayer);
    if (nLootable > 40) nLevel = nLootable;
    string sLevel = IntToString(nLevel);
    string sIP = GetPCIPAddress(oPlayer);
    string sCD = GetPCPublicCDKey(oPlayer);
    string sSQL = "SELECT pcname, charname, cdk, server  FROM loggedin WHERE pcname='" + sPlayer + "'";
    SQLExecDirect(sSQL);
    if (SQLFetch() == SQL_SUCCESS)
    {

        // row exists
        string sSQLPName = SQLGetData(1);
        string sSQLCName = SQLGetData(2);
        string sSQLCD = SQLGetData(3);
        string sSQLServer = SQLGetData(4);
        if ((sPlayer == sSQLPName) && (sName == sSQLCName) && (sCD != sSQLCD) && (sServer != sSQLServer)) //same p, c, diff cd, showing logged into diff server than this
        {
            nBoot = TRUE;//boot em, attempting double login
            WriteTimestampedLogEntry("Double Login Attempt Detected! Player: " + sUnencoded + ".");
        }
        else //they aren't attempting double login, server prolly crashed
        {
            sSQL = "UPDATE loggedin SET server='" + sServer +
                   "',charname='" + sName + "',level='" + sLevel + "',cdk='" + sCD + "',cip='" + sIP + "' WHERE pcname='"+ sPlayer + "'";
            SQLExecDirect(sSQL);
        }
    }
    else  //not foud on another server
    {
        // row doesn't exist
        sSQL = "INSERT INTO loggedin (server,pcname,charname,level,cdk,cip) VALUES" +
               "('" + sServer + "','" + sPlayer + "','" + sName + "','" + sLevel + "','" + sCD + "','" + sIP + "')";
        SQLExecDirect(sSQL);
    }
    return nBoot;
}

void DoBootPC(object oPC)
{
    if (GetIsObjectValid(oPC))
    {
        BootPC(oPC);
    }
}
void main()
{
    object oPC = GetEnteringObject();
    //I'm only including this if statement  to show that the login tracking is only done on players
    if (GetIsDM(oPC)) //verify DM Cd Keys to stop hackers
    {
        if ((!VerifyDMKey(oPC)) && (!VerifyAdminKey(oPC))) //these functions simply compare oPCs cd key to a list and return TRUE if there's a match
        {
            DoBoot(oPC);
            return;
        }
    }
    else
    {
        int nDLogin = MarkCharacterEntry(oPC);//only track players
        if (nDLogin)
        {
            DoBoot(oPC);
            return;
        }
    }
}



Onclientexit:

Code:
void MarkCharacterExit(string sPlayer, string sCharacter)
{
    string sPlayername;
    sPlayername = SQLEncodeSpecialChars(sPlayer);
    string sChar;
    sChar = SQLEncodeSpecialChars(sCharacter);
    string sServer;
    sServer = GetLocalString(OBJECT_SELF, "ServerNumber");//returns either 111 or 112
    string sSQL = "DELETE FROM loggedin WHERE pcname='" + sPlayername + "' AND server='"+sServer+"' AND charname='"+ sChar + "'";
    SQLExecDirect(sSQL);
}

void main()
{
object oPlayer = GetExitingObject();
string ID =   GetLocalString(oPlayer, "ID" ); //(PCPlayerName)//these are set oncliententer so they can be retrieved here
string NAME =    GetLocalString(oPlayer, "NAME" );
string KEY =    GetLocalString(oPlayer, "KEY" );
string IP=    GetLocalString(oPlayer, "IP"  );

//track logout
MarkCharacterExit(ID, NAME);
}


Please note that this is an important safety net on any multiserver system, because du_pers can insert an incorrect value in their ini and block master server verification, allowing them to login the same pc on the same account on two or more servers, and du_pe to their heart's content. It's also possible to login to other people's playernames this way, so I would advise adding a cd key stamp system on accounts. If you only allow one key per account, this stops the du_pe exp_lo*it, but a shocking number of players use multiple keys and computers, and that would severly inconvenience them. If you want more help or information on setting this up just let me know.
Funky
Back to top
View user's profile Send private message
FunkySwerve



Joined: 02 Jun 2005
Posts: 377

PostPosted: Sat Apr 28, 2007 23:39    Post subject: Reply with quote

Oops, use this to create the loggedin table:
Code:
#include "aps_include"

void CreateTable(object oPC)
{
    SQLExecDirect("CREATE TABLE loggedin (" +
                    "server VARCHAR(64) default NULL," +
                    "pcname VARCHAR(64) default NULL," +
                    "charname VARCHAR(64) default NULL," +
                    "level VARCHAR(64) default NULL," +
                    "KEY idx (server,pcname)" +
                    ")" );

    SendMessageToPC(oPC, "Table 'loggedin' created.");
}
void main()
{
    object oPC = GetLastUsedBy();
    CreateTable(oPC);
}

Funky
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    nwnx.org Forum Index -> Scripts and Modules All times are GMT + 2 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group