View previous topic :: View next topic |
Author |
Message |
Pwyll
Joined: 27 Apr 2007 Posts: 1
|
Posted: Fri Apr 27, 2007 19:02 Post subject: list of players on two servers --- noob |
|
|
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 |
|
|
Papillon x-man
Joined: 28 Dec 2004 Posts: 1060 Location: Germany
|
Posted: Fri Apr 27, 2007 22:57 Post subject: |
|
|
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 |
|
|
Grumalg
Joined: 04 Nov 2005 Posts: 70
|
Posted: Fri Apr 27, 2007 23:08 Post subject: |
|
|
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 |
|
|
FunkySwerve
Joined: 02 Jun 2005 Posts: 377
|
Posted: Sat Apr 28, 2007 23:38 Post subject: |
|
|
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 |
|
|
FunkySwerve
Joined: 02 Jun 2005 Posts: 377
|
Posted: Sat Apr 28, 2007 23:39 Post subject: |
|
|
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 |
|
|
|
|
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
|