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 
 
Starting from scratch... Help Virusman !

 
Post new topic   Reply to topic    nwnx.org Forum Index -> General Discussion
View previous topic :: View next topic  
Author Message
paradogz



Joined: 04 Apr 2012
Posts: 17

PostPosted: Fri Feb 07, 2014 13:20    Post subject: Starting from scratch... Help Virusman ! Reply with quote

Hello Virusman and to everyone


My name is Armand, "paradogz", I was one of the many Admins of the biggest (in terms of community) French NWN RP persistent server : Fastfrench.

It was a wonderful adventure, and today, I've received emails from various member of this community asking if the server could be back online, in order to revive Fastfrench.

I know how to run fastfrench on a Windows WAMP server, with a SQL base, but I have no knowledge about programming or server maintenance whatsoever, and I'm willing to learn. I need to get into it in order to be able to propose to the player a enjoyable and safe experience as players.

More than anything, I do not want to make the wrong choices :

I see all the work that you've done and all the features/tweaks than you have programmed are exactly what I want to use for FF (Fastfrench). Because all these functions would be ideal to encourage Role Play and FUN.

Problem is :

the module is programmed to work on a WAMP/SQL/Windows environment, and I've already tried to run it on Ubuntu precise pangolin, and it wouldn't work, even with the intervention of a very good linux technician that finally gave up.

Is there a way I can start again, implementing simple persistent function on the server, one by one ? I don't know where to start, this is frustrating, hopefully you guys will be able to guide me, especially with that FastFrench module, that have been since the beginning and is absolutely full of scripts.

I do not know where to start, but I really want to use NWNX.

Man, that would be so cool if I could get some help

thanks a lot for any replies.

Paradogz
Back to top
View user's profile Send private message
virusman



Joined: 30 Jan 2005
Posts: 1020
Location: Russia

PostPosted: Fri Feb 07, 2014 15:20    Post subject: Reply with quote

Hi paradogz,
Any information on exact errors you had when trying to run the server on Linux would help us narrow down the issue. And I don't know what modifications were in NWN-FF compared to NWNX. Could you post the NWScript includes you're using?
_________________
In Soviet Russia, NWN plays you!
Back to top
View user's profile Send private message Visit poster's website Yahoo Messenger
paradogz



Joined: 04 Apr 2012
Posts: 17

PostPosted: Fri Feb 07, 2014 16:06    Post subject: Reply with quote

Thank you for such a quick reply, I will get back very quickly (this WE) to give you all the informations you requested.

Impressed you know NWN-FF, not too much surprising to be honest !

Cheers virus, I'm plugging the server right now. (It was waiting in the depth of the wardrobe for this day Rolling Eyes )
Back to top
View user's profile Send private message
paradogz



Joined: 04 Apr 2012
Posts: 17

PostPosted: Fri Feb 14, 2014 11:14    Post subject: Reply with quote

Hi virus,

So !
./nwnstartup.sh

This is what happens :

http://imageshack.com/a/img824/4999/zaps.png

NWN FF was supposed to create its database tables on his own. I'm a bit confuse, is NWNX going to create its base automatically ?

Thanks for help

Quote:
// Name : Avlis Persistence System inclue
// Purpose : Various APS/NWNX2 related functions
// Authors : Ingmar Stieger, Adam Colon, Josh Simon
// Modified : February 16, 2003

// This file is licensed under the terms of the
// GNU GENERAL PUBLIC LICENSE (GPL) Version 2

/************************************/
/* Return codes */
/************************************/

#include "ff_inc_constant"
/************************************/
/* Function prototypes */
/************************************/

// Setup placeholders for ODBC requests and responses
void SQLInit();

// Execute statement in sSQL
void SQLExecDirect(string sSQL);

// Position cursor on next row of the resultset
// Call this before using SQLGetData().
// returns: SQL_SUCCESS if there is a row
// SQL_ERROR if there are no more rows
int SQLFetch();

// * deprecated. Use SQLFetch instead.
// Position cursor on first row of the resultset and name it sResultSetName
// Call this before using SQLNextRow() and SQLGetData().
// returns: SQL_SUCCESS if result set is not empty
// SQL_ERROR is result set is empty
//int SQLFirstRow();

// * deprecated. Use SQLFetch instead.
// Position cursor on next row of the result set sResultSetName
// returns: SQL_SUCCESS if cursor could be advanced to next row
// SQL_ERROR if there was no next row
//int SQLNextRow();

// Return value of column iCol in the current row of result set sResultSetName
string SQLGetData(int iCol);

// Return a string value when given a location
string bmLocationToString(location lLocation);

// Return a location value when given the string form of the location
location bmStringToLocation(string sLocation);

// Return a string value when given a vector
string bmVectorToString(vector vVector);

// Return a vector value when given the string form of the vector
vector StringToVector(string sVector);

// Set oObject's persistent string variable sVarName to sValue
// Optional parameters:
// iExpiration: Number of days the persistent variable should be kept in database (default: 0=forever)
// sTable: Name of the table where variable should be stored (default: pwdata)
void SetPersistentString(object oObject, string sVarName, string sValue, int iExpiration=0, string sTable="pwdata");

// Set oObject's persistent integer variable sVarName to iValue
// Optional parameters:
// iExpiration: Number of days the persistent variable should be kept in database (default: 0=forever)
// sTable: Name of the table where variable should be stored (default: pwdata)
void SetPersistentInt(object oObject, string sVarName, int iValue, int iExpiration=0, string sTable="pwdata");

// Set oObject's persistent float variable sVarName to fValue
// Optional parameters:
// iExpiration: Number of days the persistent variable should be kept in database (default: 0=forever)
// sTable: Name of the table where variable should be stored (default: pwdata)
void SetPersistentFloat(object oObject, string sVarName, float fValue, int iExpiration=0, string sTable="pwdata");

// Set oObject's persistent location variable sVarName to lLocation
// Optional parameters:
// iExpiration: Number of days the persistent variable should be kept in database (default: 0=forever)
// sTable: Name of the table where variable should be stored (default: pwdata)
// This function converts location to a string for storage in the database.
void SetPersistentLocation(object oObject, string sVarName, location lLocation, int iExpiration=0, string sTable="pwdata");

// Set oObject's persistent vector variable sVarName to vVector
// Optional parameters:
// iExpiration: Number of days the persistent variable should be kept in database (default: 0=forever)
// sTable: Name of the table where variable should be stored (default: pwdata)
// This function converts vector to a string for storage in the database.
void SetPersistentVector(object oObject, string sVarName, vector vVector, int iExpiration=0, string sTable ="pwdata");

// Get oObject's persistent string variable sVarName
// Optional parameters:
// sTable: Name of the table where variable is stored (default: pwdata)
// * Return value on error: ""
string GetPersistentString(object oObject, string sVarName, string sTable="pwdata");

// Get oObject's persistent integer variable sVarName
// Optional parameters:
// sTable: Name of the table where variable is stored (default: pwdata)
// * Return value on error: 0
int GetPersistentInt(object oObject, string sVarName, string sTable="pwdata");

// Get oObject's persistent float variable sVarName
// Optional parameters:
// sTable: Name of the table where variable is stored (default: pwdata)
// * Return value on error: 0
float GetPersistentFloat(object oObject, string sVarName, string sTable="pwdata");

// Get oObject's persistent location variable sVarName
// Optional parameters:
// sTable: Name of the table where variable is stored (default: pwdata)
// * Return value on error: 0
location GetPersistentLocation(object oObject, string sVarname, string sTable="pwdata");

// Get oObject's persistent vector variable sVarName
// Optional parameters:
// sTable: Name of the table where variable is stored (default: pwdata)
// * Return value on error: 0
vector GetPersistentVector(object oObject, string sVarName, string sTable = "pwdata");

// Delete persistent variable sVarName stored on oObject
// Optional parameters:
// sTable: Name of the table where variable is stored (default: pwdata)
void DeletePersistentVariable(object oObject, string sVarName, string sTable="pwdata");

// (private function) Replace special character ' with ~
string SQLEncodeSpecialChars(string sString);


void ff_SetXP(object oPlayer, int iXP, int PerteNiveau=TRUE); // Positionne en meme temps la variable

string ff_Colorize(string sText);

location ff_GetDefaultRecallLocation(object oPlayer);

/*****************************************
** New FF specific RCO/SCO substitutes ** (NWN-FF 4.1.0+)
*****************************************/
// Store an object for that PC on a specific Placable (chest...)
void ff_SetPersistentObject(object oOwner, object oObject, object oPlacable=OBJECT_INVALID, string sTable = "RCO_SCO");
// Retreive the first object for that PC on a specific Placable (chest...)
object ff_GetPersistentObjectFirst(object oOwner, object oPlacable=OBJECT_INVALID, string sTable = "RCO_SCO");
// Retreive the next objects ('til return NULL)
object ff_GetPersistentObjectNext(object oOwner, object oPlacable=OBJECT_INVALID);
// Remove all objects associated with that player on a given placable
void ff_CleanPersistentObject(object oOwner, object oPlacable=OBJECT_INVALID, string sTable = "RCO_SCO");


/************************************/
/* Implementation */
/************************************/

// Functions for initializing APS and working with result sets
object oSpecific=OBJECT_INVALID;
string LOCAL_BUFFER;

object GetNWNMySQLWP()
{
if (oSpecific != OBJECT_INVALID) return oSpecific;
oSpecific = GetWaypointByTag("NWN_MySQL_WP");
if (oSpecific != OBJECT_INVALID) return oSpecific;
//oSpecific = CreateObject(OBJECT_TYPE_WAYPOINT,
oSpecific = GetModule();
return oSpecific;
}

void SQLInit()
{
int i;

// Placeholder for ODBC persistence
string sMemory;
oSpecific = GetWaypointByTag("NWN_MySQL_WP");
if (oSpecific == OBJECT_INVALID)
CreateObject(OBJECT_TYPE_WAYPOINT, "nw_waypoint001",GetStartingLocation(),FALSE,"NWN_MySQL_WP");
for (i = 0; i < 8; i++) // reserve 8*128 bytes
sMemory += "................................................................................................................................";

SetLocalString(GetNWNMySQLWP(), "NWNX!ODBC!SPACER", sMemory);

}

/*
* This part can be included in aps_include (copy/past or add # include "aps_include2.nss" at start)
* Only some are specific to NWN-MySQL.
* All ExecAndFetch functions could easily be simulated with NWNX2 (but with highly decreased performances)
* Only SQLGetTime is really very specific and can't be done without NWN-MySQL. With older version, it will
* simply return 0 all the time (good hint to check if you're using NWN-MySQL).
*/

/*************************************
* (c) FastFrench Optimized functions *
*********$$$$*************************/
// *** NWN-MySQL SPECIFIC. Won't work with NWNX version 2.0.3 or older ***
int SQLLocalFetch()
{
object oLocal = GetNWNMySQLWP();
SetLocalString(oLocal, "NWNX!ODBC!FETCH", GetLocalString(oLocal, "NWNX!ODBC!SPACER"));
LOCAL_BUFFER = GetLocalString(oLocal, "NWNX!ODBC!FETCH");
if (GetStringLength(LOCAL_BUFFER) > 0)
return SQL_SUCCESS;
else
return SQL_ERROR;
}


int SQLExecAndFetchDirect(string sSQL) // Safe for result sets under (129+size of request) characters long
{
object oLocal = GetNWNMySQLWP();
string sBuf = sSQL + "¬................................................................................................................................";
SetLocalString(oLocal, "NWNX!ODBC!EXEC_AND_FETCH", sBuf);
sBuf = GetLocalString(oLocal, "NWNX!ODBC!EXEC_AND_FETCH");
if (GetStringLength(sBuf) > 0)
{
SetLocalString(oLocal, "NWNX_ODBC_CurrentRow", sBuf);
return SQL_SUCCESS;
}
else
{
DeleteLocalString(oLocal, "NWNX_ODBC_CurrentRow");
return SQL_ERROR;
}
}

// *** NWN-MySQL SPECIFIC. Won't work with NWNX version 2.0.3 or older ***
string SQLExecAndFetchSingle(string sSQL, string DefaultValue="") // FAST and Safe for result sets under (size of request) characters long AND ONLY ONE VALUE RETURNED
{
SetLocalString(GetNWNMySQLWP(), "NWNX!ODBC!EXEC_AND_FETCH", sSQL);
string sRes = GetLocalString(GetNWNMySQLWP(), "NWNX!ODBC!EXEC_AND_FETCH");
if (sRes == "") return DefaultValue;
return sRes;
}

// *** NWN-MySQL SPECIFIC. Won't work with NWNX version 2.0.3 or older ***
int SQLExecAndFetchSingleInt(string sSQL, int DefaultValue=0) // FAST and Safe for result sets under (size of request) characters long AND ONLY ONE VALUE RETURNED
{
SetLocalString(GetNWNMySQLWP(), "NWNX!ODBC!EXEC_AND_FETCH", sSQL);
//string sRes = GetLocalString(GetModule(), "NWNX!ODBC!EXEC_AND_FETCH");
//if (sRes=="") return 0;
string sRes = GetLocalString(GetNWNMySQLWP(), "NWNX!ODBC!EXEC_AND_FETCH");
if (sRes == "") return DefaultValue;
return StringToInt(sRes);
}

// *** NWN-MySQL SPECIFIC. Won't work with NWNX version 2.0.3 or older ***
int SQLGetTime() // Gives the number of micro-seconds since NWServer started
{
SetLocalString(GetNWNMySQLWP(), "NWNX!TIMER", "000000000000");
return StringToInt(GetLocalString(GetNWNMySQLWP(), "NWNX!TIMER"));
}

// *** NWN-FF SPECIFIC. Won't work before NWN-FF 4.0.3
string SQLGetServer()
{
SetLocalString(GetNWNMySQLWP(), "NWNX!SERVER", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
return GetLocalString(GetNWNMySQLWP(), "NWNX!SERVER");
}

// *** NWN-FF SPECIFIC. Won't work before NWN-FF 4.0.3
string SQLGetModule()
{
SetLocalString(GetNWNMySQLWP(), "NWNX!MODULE", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
return GetLocalString(GetNWNMySQLWP(), "NWNX!MODULE");
}

// *** NWN-FF SPECIFIC. Won't work before NWN-FF 4.0.4
int SQLGetCRC(string sText)
{
SetLocalString(GetNWNMySQLWP(), "NWNX!CRC", sText);
return StringToInt(GetLocalString(GetNWNMySQLWP(), "NWNX!CRC"));
}

// *** NWN-FF SPECIFIC. Won't work before NWN-FF 4.0.4
string SQLCode(string sText)
{
SetLocalString(GetNWNMySQLWP(), "NWNX!CODING", sText);
return GetLocalString(GetNWNMySQLWP(), "NWNX!CODING");
}

// *** NWN-FF SPECIFIC. Won't work before NWN-FF 4.0.4
int SQLGetTimeInSecond() // Gives the number of micro-seconds since NWServer started
{
SetLocalString(GetNWNMySQLWP(), "NWNX!SECONDS", "000000000000");
return StringToInt(GetLocalString(GetNWNMySQLWP(), "NWNX!SECONDS"));
}

string SQLGetVersion() // Returns version string for NWN-MySQL
{
SetLocalString(GetNWNMySQLWP(), "NWNX!VERSION", "APS/NWNX");
return GetLocalString(GetNWNMySQLWP(), "NWNX!VERSION");
}

int SQLGetRLDate() // Returns the number of second since january 1st 2001 (in RL world)
{
SetLocalString(GetNWNMySQLWP(), "NWNX!RLDATE", "000000000000000000000000000000000");
return StringToInt(GetLocalString(GetNWNMySQLWP(), "NWNX!RLDATE"));
}


void SQLSetIGDate()
{
int GetRLDate=SQLGetRLDate();
int NbMinPerHour = FloatToInt(HoursToSeconds(1)) / 60;
int iSecond = GetRLDate % 60;
GetRLDate = GetRLDate / 60;
int iMinute = GetRLDate % NbMinPerHour;
GetRLDate = GetRLDate / NbMinPerHour;
int iHour = GetRLDate % 24;
GetRLDate = GetRLDate / 24;
int iDay = GetRLDate % 28 + 1;
GetRLDate = GetRLDate / 28;
int iMonth = GetRLDate % 12 + 1;
GetRLDate = GetRLDate / 12;
int iYear = 1001+GetRLDate;

SetTime(iHour, iMinute, iSecond, 0);
SetCalendar(iYear, iMonth, iDay);
//WriteTimestampedLogEntry("Set IG time: "+IntToString(iDay)+"/"+IntToString(iMonth)+"/"+IntToString(iYear)+" - "+IntToString(iHour)+":"+IntToString(iMinute)+":"+IntToString(iSecond));
}


// Get Next Data
string SQLEatData()
{
string sResultSet = GetLocalString(GetNWNMySQLWP(), "NWNX_ODBC_CurrentRow");

// find column in current row

int iPos = FindSubString(sResultSet, "¬");
if (iPos == -1) // Une seule colonne
{
// only one column, return value immediately et efface la chaine
DeleteLocalString(GetNWNMySQLWP(), "NWNX_ODBC_CurrentRow");
return sResultSet;
}
else
{
SetLocalString(GetNWNMySQLWP(), "NWNX_ODBC_CurrentRow", GetStringRight(sResultSet,GetStringLength(sResultSet) - iPos - 1));
return GetStringLeft(sResultSet, iPos);
}
}

// Skip next data (like SQLEatData, except it returns nothing)
void SQLSkipData()
{
string sResultSet = GetLocalString(GetNWNMySQLWP(), "NWNX_ODBC_CurrentRow");


int iPos = FindSubString(sResultSet, "¬");
if (iPos == -1) // Une seule colonne
// only one column, return value immediately et efface la chaine
DeleteLocalString(GetNWNMySQLWP(), "NWNX_ODBC_CurrentRow");
else
SetLocalString(GetNWNMySQLWP(), "NWNX_ODBC_CurrentRow", GetStringRight(sResultSet,GetStringLength(sResultSet) - iPos - 1));
}

/* All related SQLLocalXXXX functions need to be used within a single file.
It means gor instance that if you make a call to SQLLocalExecAndFetchDirect and several calls to SQLLocalEatData to get corresponding results,
then you have to put all those instruction in the same scipt file (to make it easier, let say all call should better be in a single script) - using shared string
if you can't, then better use the less optimized SQLXXX equivalent (SQLExecAndFetchDirect and SQLEatData for instance), not the very optimized SQLLocalXXXX */

// *** NWN-MySQL SPECIFIC. Won't work with NWNX version 2.0.3 or older ***
int SQLLocalExecAndFetchDirect(string sSQL) // Safe for result sets under (129+size of request) characters long - store result locally
{
LOCAL_BUFFER = sSQL + "¬................................................................................................................................";
SetLocalString(GetNWNMySQLWP(), "NWNX!ODBC!EXEC_AND_FETCH", LOCAL_BUFFER);
LOCAL_BUFFER = GetLocalString(GetNWNMySQLWP(), "NWNX!ODBC!EXEC_AND_FETCH");
//WriteTimestampedLogEntry("In:"+sSQL);
//WriteTimestampedLogEntry("Out:"+LOCAL_BUFFER);

if (GetStringLength(LOCAL_BUFFER) > 0)
return SQL_SUCCESS;
else
return SQL_ERROR;
}

// Get Next Data
string SQLLocalEatData()
{
int iPos;

// find column in current row
//int iCount = 0;
string Result;
iPos = FindSubString(LOCAL_BUFFER, "¬");
if (iPos == -1) // Une seule colonne
{
// only one column, return value immediately et efface la chaine
Result = LOCAL_BUFFER;
LOCAL_BUFFER = "";
return Result;
}
else
{
Result = GetStringLeft(LOCAL_BUFFER, iPos);
LOCAL_BUFFER = GetStringRight(LOCAL_BUFFER,GetStringLength(LOCAL_BUFFER) - iPos - 1);
return Result;
}
}

// Get Next Data
void SQLLocalSkipData()
{
int iPos;

// find column in current row
//int iCount = 0;
string Result;
iPos = FindSubString(LOCAL_BUFFER, "¬");
if (iPos == -1) // Une seule colonne
{
// only one column, return value immediately et efface la chaine
LOCAL_BUFFER = "";
}
else
{
LOCAL_BUFFER = GetStringRight(LOCAL_BUFFER,GetStringLength(LOCAL_BUFFER) - iPos - 1);
}
}

// Get Next Data
int SQLLocalEatDataInt()
{
int iPos;

// find column in current row
//int iCount = 0;
int Result;
iPos = FindSubString(LOCAL_BUFFER, "¬");
if (iPos == -1) // Une seule colonne
{
// only one column, return value immediately et efface la chaine
Result = StringToInt(LOCAL_BUFFER);
LOCAL_BUFFER = "";
return Result;
}
else
{
Result = StringToInt(GetStringLeft(LOCAL_BUFFER, iPos));
LOCAL_BUFFER = GetStringRight(LOCAL_BUFFER,GetStringLength(LOCAL_BUFFER) - iPos - 1);
return Result;
}
}

int bmGetPersistentInt(string ValueName, int DefaultValue=0)
{
return SQLExecAndFetchSingleInt("SELECT Value FROM global WHERE VarName='"+ValueName+"'",DefaultValue);
}

string bmGetPersistentString(string ValueName, string DefaultValue="")
{
return SQLExecAndFetchSingle("SELECT Value FROM global WHERE VarName='"+ValueName+"'¬................................................................................................................................................................................................................",DefaultValue);
}

void bmSetPersistentInt(string ValueName, int iValue)
{
SQLExecDirect("REPLACE global SET Value="+IntToString(iValue)+", VarName='"+ValueName+"'");
}

void bmSetPersistentString(string ValueName, string sValue)
{
SQLExecDirect("REPLACE global SET Value='"+SQLEncodeSpecialChars(sValue)+"', VarName='"+ValueName+"'");
}


int SQLFastGetPersistentInt(string ValueName, string sTable="global")
{
return SQLExecAndFetchSingleInt("SELECT Value FROM "+sTable+" WHERE VarName='"+ValueName+"'");
}

string SQLFastGetPersistentString(string ValueName, string sTable="global")
{
return SQLExecAndFetchSingle("SELECT Value FROM "+sTable+" WHERE VarName='"+ValueName+"'¬................................................................................................................................................................................................................");
}

void SQLFastSetPersistentInt(string ValueName, int iValue, string sTable="global")
{
SQLExecDirect("REPLACE "+sTable+" SET Value="+IntToString(iValue)+", VarName='"+ValueName+"'");
}

void SQLFastSetPersistentString(string ValueName, string sValue, string sTable="global")
{
SQLExecDirect("REPLACE "+sTable+" SET Value='"+SQLEncodeSpecialChars(sValue)+"', VarName='"+ValueName+"'");
}

void SQLFastSetPersistentLocation(string ValueName, location lValue, string sTable="global")
{
SQLExecDirect("REPLACE "+sTable+" SET Value="+bmLocationToString(lValue)+", VarName='"+ValueName+"'");
}

location SQLFastGetPersistentLocation(string ValueName, string sTable="global")
{
return bmStringToLocation(SQLExecAndFetchSingle("SELECT Value FROM "+sTable+" WHERE VarName='"+ValueName+"'¬................................................................................................................................................................................................................"));
}

void SQLFastDeletePersistentVariable(string ValueName, string sTable="global")
{
SQLExecDirect("DELETE from "+sTable+" WHERE VarName='"+ValueName+"'");
}

/*****************************************
* END of FastFrench Optimized functions *
***************$$$$$$********************/

void SQLExecDirect(string sSQL)
{
SetLocalString(GetNWNMySQLWP(), "NWNX!ODBC!EXEC", sSQL);
}

int SQLFetch()
{
object oWP = GetNWNMySQLWP();
SetLocalString(oWP, "NWNX!ODBC!FETCH", GetLocalString(oWP, "NWNX!ODBC!SPACER"));
string sRow = GetLocalString(oWP, "NWNX!ODBC!FETCH");
if (GetStringLength(sRow) > 0)
{
SetLocalString(oWP, "NWNX_ODBC_CurrentRow", sRow);
return SQL_SUCCESS;
}
else
{
SetLocalString(oWP, "NWNX_ODBC_CurrentRow", "");
return SQL_ERROR;
}
}


string SQLGetData(int iCol)
{
int iPos;
string sResultSet = GetLocalString(GetNWNMySQLWP(), "NWNX_ODBC_CurrentRow");

// find column in current row
int iCount = 0;
string sColValue = "";

iPos = FindSubString(sResultSet, "¬");
if ((iPos == -1) && (iCol == 1))
{
// only one column, return value immediately
sColValue = sResultSet;
}
else if (iPos == -1)
{
// only one column but requested column > 1
sColValue = "";
}
else
{
// loop through columns until found
while (iCount != iCol)
{
iCount++;
if (iCount == iCol)
sColValue = GetStringLeft(sResultSet, iPos);
else
{
sResultSet = GetStringRight(sResultSet,GetStringLength(sResultSet) - iPos - 1);
iPos = FindSubString(sResultSet, "¬");
}

// special case: last column in row
if (iPos == -1)
iPos = GetStringLength(sResultSet);
}
}

return sColValue;
}


// These functions deal with various data types. Ultimately, all information
// must be stored in the database as strings, and converted back to the proper
// form when retrieved.

string bmVectorToString(vector vVector)
{
return "#X#" + FloatToString(vVector.x,8,4) + "#Y#" + FloatToString(vVector.y,8,4) + "#Z#" + FloatToString(vVector.z,8,4) + "#E#";
}

vector StringToVector(string sVector)
{
float fX, fY, fZ;
int iPos, iCount;
int iLen = GetStringLength(sVector);

if (iLen > 0)
{
iPos = FindSubString(sVector, "#X#") + 3;
iCount = FindSubString(GetSubString(sVector, iPos, iLen - iPos), "#");
fX = StringToFloat(GetSubString(sVector, iPos, iCount));

iPos = FindSubString(sVector, "#Y#") + 3;
iCount = FindSubString(GetSubString(sVector, iPos, iLen - iPos), "#");
fY = StringToFloat(GetSubString(sVector, iPos, iCount));

iPos = FindSubString(sVector, "#Z#") + 3;
iCount = FindSubString(GetSubString(sVector, iPos, iLen - iPos), "#");
fZ = StringToFloat(GetSubString(sVector, iPos, iCount));
}

return Vector(fX, fY, fZ);
}


string bmLocationToString(location lLocation)
{
object oArea = GetAreaFromLocation(lLocation);
string sReturnValue;

if (GetIsObjectValid(oArea))
{
vector vPosition = GetPositionFromLocation(lLocation);
float fOrientation = GetFacingFromLocation(lLocation);
sReturnValue = "#A#" + GetTag(oArea) + "#X#" + FloatToString(vPosition.x,8,4) + "#Y#" + FloatToString(vPosition.y,8,4) + "#Z#" + FloatToString(vPosition.z,8,4) + "#O#" + FloatToString(fOrientation,8,4) + "#E#";
}
else
sReturnValue = "#A##X#0.0#Y#0.0#Z#0.0#O#0.0#E#";
return sReturnValue;
}

location bmStringToLocation(string sLocation)
{
location lReturnValue=Location(OBJECT_INVALID, Vector(),0.0);
object oArea;
vector vPosition;
float fOrientation, fX, fY, fZ;

int iPos, iCount;
int iLen = GetStringLength(sLocation);

if (iLen > 0)
{
iPos = FindSubString(sLocation, "#A#") + 3;
iCount = FindSubString(GetSubString(sLocation, iPos, iLen - iPos), "#");
if (iCount > 0)
{
oArea = GetObjectByTag(GetSubString(sLocation, iPos, iCount));
if (GetIsObjectValid(oArea))
{
iPos = FindSubString(sLocation, "#X#") + 3;
iCount = FindSubString(GetSubString(sLocation, iPos, iLen - iPos), "#");
fX = StringToFloat(GetSubString(sLocation, iPos, iCount));

iPos = FindSubString(sLocation, "#Y#") + 3;
iCount = FindSubString(GetSubString(sLocation, iPos, iLen - iPos), "#");
fY = StringToFloat(GetSubString(sLocation, iPos, iCount));

iPos = FindSubString(sLocation, "#Z#") + 3;
iCount = FindSubString(GetSubString(sLocation, iPos, iLen - iPos), "#");
fZ = StringToFloat(GetSubString(sLocation, iPos, iCount));

vPosition = Vector(fX, fY, fZ);

iPos = FindSubString(sLocation, "#O#") + 3;
iCount = FindSubString(GetSubString(sLocation, iPos, iLen - iPos), "#");
fOrientation = StringToFloat(GetSubString(sLocation, iPos, iCount));

lReturnValue = Location(oArea, vPosition, fOrientation);
}
}
}

return lReturnValue;
}

// Simple log informations into the log database, with just 2 classification field (Id player and Categorie)
void pwWriteLog2(object oPlayer, string sCategorie, string sTexte)
{
string sId = GetLocalString(oPlayer, "PWId");
if (StringToInt(sId)<=0)
if (GetIsPC(oPlayer)) sId = "99999";
else sId = "99998";
string sSQL = "INSERT INTO poubelle (Id,Categorie,Texte) VALUES(" + sId + ",'"+SQLEncodeSpecialChars(sCategorie)+"','"+SQLEncodeSpecialChars(sTexte)+"')";
SQLExecDirect(sSQL);
}

// log informations into the log database, with 3 classification fields
void pwWriteLog(object oPlayer, string sCategorie, string sSubCategorie, string sTexte)
{
string sId = GetLocalString(oPlayer, "PWId");
if (StringToInt(sId)<=0)
if (GetIsPC(oPlayer)) sId = "99999";
else sId = "99998";
string sSQL = "INSERT INTO log (Id,Categorie,SubCategorie,Texte) VALUES(" + sId + ",'"+SQLEncodeSpecialChars(sCategorie)+"','"+SQLEncodeSpecialChars(sSubCategorie)+"','"+SQLEncodeSpecialChars(sTexte)+"')";
SQLExecDirect(sSQL);
}

// log informations de connexion uniquement
void pwWriteLogCon(object oPlayer, string sCategorie)
{
string sId = GetLocalString(oPlayer, "PWId");
if (sId=="") return;
// {
// WriteTimestampedLogEntry("["+sCategorie+"] **MySQL Failed** "+GetName(oPlayer)+" ("+GetPCPlayerName(oPlayer)+")");
// return;
// }
string sSQL;
if(sId=="0")
sSQL = "INSERT INTO login (Id,Event) VALUES(" + sId + ",'"+sCategorie+"')";
else
sSQL = "INSERT INTO login (Id,Event,Gold,xp,IP,sKey) VALUES(" + sId + ",'"+sCategorie+"',"+IntToString(GetGold(oPlayer))+","+IntToString(GetXP(oPlayer))+",'"+SQLEncodeSpecialChars(GetPCIPAddress(oPlayer))+"','"+SQLEncodeSpecialChars(GetPCPublicCDKey(oPlayer))+"')";
SQLExecDirect(sSQL);
}

void InitValues(object oPlayer)
{
int i;
// for (i=1; i<=CINT_SKILL_COUNT; i++)
// ff_SetTradeskill(oPlayer, i, 0, FALSE);
SetLocalLocation(oPlayer, "Position", Location(OBJECT_INVALID, Vector(),0.0));
SetLocalLocation(oPlayer, "Recall", Location(OBJECT_INVALID, Vector(),0.0));
SetLocalInt( oPlayer, "Home", 0);
SetLocalInt( oPlayer, "Or_banque", 0);
SetLocalInt( oPlayer, "RP", 0);
SetLocalInt( oPlayer, "Time", 0);
SetLocalInt( oPlayer, "CraftXP", 0);
SetLocalInt( oPlayer, "Permis", 0);
SetLocalInt( oPlayer, "Boulets", 0);
SetLocalInt( oPlayer, "Avis", 0);
SetLocalInt( oPlayer, "Damage", 0);
SetLocalInt( oPlayer, "Guild", 0);
SetLocalInt( oPlayer, "Guild_rank", 0);
SetLocalInt( oPlayer, "PK_BAD", 0);
SetLocalInt( oPlayer, "VOL", 0);
SetLocalInt( oPlayer, "PKED", 0);
SetLocalInt( oPlayer, "PK_OK", 0);
SetLocalInt( oPlayer, "Jailed", 0);
SetLocalInt( oPlayer, "LastLevelTime", 0);
SetLocalInt( oPlayer, "LevelCap", 3);
SetLocalInt( oPlayer, "Level", GetHitDice(oPlayer));
SetLocalInt( oPlayer, "XP", GetXP(oPlayer));
SetLocalInt( oPlayer, "Gold", GetGold(oPlayer));
SetLocalInt( oPlayer, "Flags", 0);
}

// Call this function as often as you wish.
// For instance in each area transition, after each rest, death, cure, resur, end of fight...
void ff_FastFlushData(object oPC)
{
////
if (oPC==OBJECT_INVALID) return;
//if (!GetIsPC(oPC)) return;
if (GetLocalInt(oPC, "InitRunning")>0) return;
string sId = GetLocalString(oPC, "PWId");
if (sId=="") return;
if (StringToInt(sId)<=0) return;


//int bAnyChange = TRUE;

int iMaxHP = GetMaxHitPoints(oPC);
if (iMaxHP<=0) return;


location lPos = GetLocation(oPC);
object oArea = GetAreaFromLocation(lPos);

string sSQL = "UPDATE PlayerData SET ";
sSQL += "Time="+IntToString(GetLocalInt(oPC, "Time"));
if (GetIsObjectValid(oArea))
{
SetLocalLocation(oPC, "Position", lPos);
sSQL += ", Position='"+bmLocationToString(lPos)+"'";
}
if (GetIsObjectValid(oPC))
{
int iCurrentHP = GetCurrentHitPoints(oPC);
int iDamage = iMaxHP-iCurrentHP;
if (GetIsDead(oPC)) iDamage = iMaxHP+50;
if (iDamage<0) iDamage=0;
SetLocalInt(oPC, "Damage", iDamage);
sSQL += ", Damage="+IntToString(iDamage);
}
sSQL += " WHERE Id="+sId;
SQLExecDirect(sSQL);
}


void ff_FlushData(object oPlayer, int Level=0)
{
string sId = GetLocalString(oPlayer, "PWId");
if (sId=="") return;
string sSQL = "UPDATE PlayerData SET ";
location lPos = GetLocalLocation(oPlayer, "Position");
if (GetIsObjectValid(GetAreaFromLocation(lPos)))
sSQL += "Position='"+bmLocationToString(lPos)+"',";
sSQL += "Time="+IntToString(GetLocalInt(oPlayer, "Time"))+",";
if (Level>0)
{
sSQL += "Permis="+IntToString(GetLocalInt(oPlayer, "Permis"))+",";
sSQL += "Boulets="+IntToString(GetLocalInt(oPlayer, "Boulets"))+",";
sSQL += "Avis="+IntToString(GetLocalInt(oPlayer, "Avis"))+",";
sSQL += "PK_BAD="+IntToString(GetLocalInt(oPlayer, "PK_BAD"))+",";
sSQL += "VOL="+IntToString(GetLocalInt(oPlayer, "VOL"))+",";
sSQL += "PKED="+IntToString(GetLocalInt(oPlayer, "PKED"))+",";
sSQL += "PK_OK="+IntToString(GetLocalInt(oPlayer, "PK_OK"))+",";
}
sSQL += "Damage="+IntToString(GetLocalInt(oPlayer, "Damage"))+",";
int nXP = GetLocalInt(oPlayer, "XP");
if (nXP == 0) nXP = GetXP(oPlayer);
sSQL += "XP="+IntToString(nXP)+",";
sSQL += "Gold="+IntToString(GetGold(oPlayer));
//sSQL += "Jailed="+IntToString(GetLocalInt(oPlayer, "Jailed")/60);
sSQL += " WHERE Id="+sId;
SQLExecDirect(sSQL);
}

int IsLowerCase(string oS)
{
if (GetStringLowerCase(oS)==oS) return TRUE;
return FALSE;
}

int IsUpperCase(string oS)
{
if (GetStringUpperCase(oS)==oS) return TRUE;
return FALSE;
}

int HasValidName(object oPlayer)
{
int NbLowercase=0;
int NbDigit=0;
int NbUpcase=0;
string sName = GetName(oPlayer);
int i;
int iLen = GetStringLength(sName);
int bUp, bLow;
string sSub;
int bValid=TRUE;
if (GetIsDM(oPlayer)) return FALSE; //Les DM doivent etre valides manuellement (FindSubString(sName, "(DM)")!=-1); // Si c'est un DM, il doit avoir (DM) dans son nom
else
if (FindSubString(sName, "(DM)")!=-1) return FALSE; // Sinon, c'est interdit

for (i=0; i<iLen; i++)
{
sSub = GetSubString(sName, i, 1);
bUp = IsUpperCase(sSub);
bLow = IsLowerCase(sSub);
if (bLow==bUp)
{NbDigit++;if (sSub == "[" || sSub == "]" || sSub == "{" || sSub == "}" || sSub == "^") bValid = FALSE;}
else
if (bLow) NbLowercase++;
else
NbUpcase++;
}

if (NbUpcase>=NbLowercase) return FALSE;
if (NbLowercase<3) return FALSE;
int NbMaxi = 4;
if (FindSubString(sName, "*Garde de Lyon*")!=-1 || FindSubString(sName, "*Juge de Lyon*")!=-1)
NbMaxi = 10;


if ((NbDigit + NbUpcase) > NbMaxi)
return FALSE;
return bValid;
}

void ReportGold(object oPlayer, int iStored, int iback)
{
int dif = abs(iStored-iback);
if ((dif > 1000) && ((dif>iStored/2) || (dif>iback/2)))
pwWriteLog2(oPlayer, "GOLD", "devrait avoir "+IntToString(iStored)+", en avait "+IntToString(iback)+" et en a maintenant "+IntToString(GetGold(oPlayer)));
}

int SelectPersistentChar(object oPlayer)
{
string sPlayer = SQLEncodeSpecialChars(GetPCPlayerName(oPlayer));
string sName = SQLEncodeSpecialChars(GetName(oPlayer));
string sKey = GetPCPublicCDKey(oPlayer);
string sKey2, sSQL, sId, sNewRecord;
int iVersion=1;

// Table1 (cdkeys) (Player, CDKey, Date{TS})
// Table2 (idplayer) (Player, Name, Creation{TS}, Id{auto})
// Table3 (pwdata) (Id, Data, Date{TS})
// Table4 (log) (Id, Date{TS}, Categorie, SubCategorie, Texte)

// Mise a jour table des clefs CD
int iRes = SQLLocalExecAndFetchDirect("SELECT Ban FROM cdkeys WHERE (Player='" + sPlayer + "' OR Player='*') AND (CDKey='" + sKey+"' OR CDKey='*')");

if (iRes != SQL_SUCCESS) // This player/CDKey pair doesn't exist yet
SQLExecDirect("INSERT INTO cdkeys (Player,CDKey) VALUES('" + sPlayer + "','" + sKey + "')");
else
{
if (SQLLocalEatDataInt()==1)
{
SetLocalInt(GetModule(),GetPCPlayerName(oPlayer)+"_BAN", 1); // Banni par un DM online -> ejecte (jusqu'au prochain demarrage)
pwWriteLog(oPlayer, "LOGIN", "REJET PERSO", "cdkeys Ban=1 pour "+GetName(oPlayer)+": Player="+sPlayer+", CDKey="+sKey);
BootPC(oPlayer);
return FALSE;
}
}

// Mise a jour
iRes = SQLLocalExecAndFetchDirect("SELECT Id,Version,Ban,CDKey,DM FROM idplayer WHERE Player='" + sPlayer + "' AND Name='" + sName + "'");
int bNewRecord = FALSE;
int bValid = TRUE;

if (iRes != SQL_SUCCESS) // New character
{
bValid = HasValidName(oPlayer);
if (bValid)
{
iRes = SQLLocalExecAndFetchDirect("SELECT Id FROM idplayer WHERE Name='" + sName + "' AND Ban=0");
if (iRes==SQL_SUCCESS) // This name is allready currently used !
{
bValid = FALSE;
pwWriteLog(oPlayer, "LOGIN", "REJET PERSO", "Nom deja utilise:"+GetName(oPlayer)+" (Id:"+SQLLocalEatData()+")");
SendMessageToAllDMs(GetName(oPlayer)+" a ete automatiquement rejete (nom deja utilise)");
}
}
else
{
pwWriteLog(oPlayer, "LOGIN", "REJET PERSO", "Nom invalide:"+GetName(oPlayer));
SendMessageToAllDMs(GetName(oPlayer)+" (nouveau perso) a ete automatiquement rejete (nom invalide)");
}

SQLExecDirect("INSERT INTO idplayer (Player,Name,Version,DM,Creation,Ban) VALUES('" + sPlayer + "','" + sName + "',3,"+IntToString(GetIsDM(oPlayer))+",NOW(),"+IntToString(!bValid)+")"); // Actuellement version 3
iRes = SQLLocalExecAndFetchDirect("SELECT Id,Version,Ban,CDKey,DM FROM idplayer WHERE Player='" + sPlayer + "' AND Name='" + sName + "'");
bNewRecord = TRUE;
}

if (iRes == SQL_SUCCESS) // This character allready exists
{
sId = SQLLocalEatData();
iVersion = SQLLocalEatDataInt();
if (SQLLocalEatDataInt())
{
pwWriteLog(oPlayer, "LOGIN", "REJET PERSO", "Ban=1 pour "+GetName(oPlayer));
BootPC(oPlayer);
return FALSE;
}
SetLocalString(oPlayer, "PWId", sId);
string sKey = SQLLocalEatData();
if (sKey != "")
{
if (sKey != GetPCPublicCDKey(oPlayer))
{
pwWriteLog(oPlayer, "LOGIN", "REJET PERSO", "CDKey invalide - '"+GetPCPublicCDKey(oPlayer)+"' au lieu de '"+sKey+"' attendue");
BootPC(oPlayer);
return FALSE;
}
}
int iId = StringToInt(sId);
if (iId <= 0) {BootPC(oPlayer); return FALSE;}
if (!bValid)
{
DelayCommand(5.0,SendMessageToPC(oPlayer,"Votre nom n'est pas correct ou est deja utilise, refaites un autre personnage en soignant la description et en choisissant un nom original et RP"));
DelayCommand(80.0,BootPC(oPlayer));
return FALSE;
}
int bReset = (iVersion != 3 || bNewRecord);

int iDM = SQLLocalEatDataInt(); // DM range
if (iDM==2)
SetLocalInt(oPlayer, "DM_STATUS", LV_ANIM1);
else
if (iDM==3)
SetLocalInt(oPlayer, "DM_STATUS", LV_ANIM2);
else
if (iDM==4)
SetLocalInt(oPlayer, "DM_STATUS", LV_DM);
else
if (iDM==5)
SetLocalInt(oPlayer, "DM_STATUS", LV_DM_SR);
else
if (iDM==6)
SetLocalInt(oPlayer, "DM_STATUS", LV_ADMIN);


if (!bReset)
{
iRes = SQLLocalExecAndFetchDirect("SELECT Techniques,Position,Recall,Home,Or_banque,RP,Time,CraftXP,Permis,Boulets,Avis,Damage,Guild,Guild_rank,PK_BAD,VOL,PKED,PK_OK,Jailed,LastLevelTime,LevelCap,Level,Flags,XP,Gold,PrestigeClass FROM PlayerData WHERE Id=" + sId);
if (iRes == SQL_SUCCESS)
{
SetLocalString( oPlayer, "Techniques", SQLLocalEatData());
SetLocalLocation(oPlayer, "Position", bmStringToLocation(SQLLocalEatData()));
string sRecall = SQLLocalEatData();
location lLocation;
if (sRecall=="")
{
lLocation = ff_GetDefaultRecallLocation(oPlayer);
SetLocalLocation(oPlayer, "Recall", lLocation);
}
else
SetLocalLocation(oPlayer, "Recall", bmStringToLocation(sRecall));
SetLocalInt( oPlayer, "Home", SQLLocalEatDataInt());
SetLocalInt( oPlayer, "Or_banque", SQLLocalEatDataInt());
SetLocalInt( oPlayer, "RP", SQLLocalEatDataInt());
SetLocalInt( oPlayer, "Time", SQLLocalEatDataInt());
SetLocalInt( oPlayer, "CraftXP", SQLLocalEatDataInt());
SetLocalInt( oPlayer, "Permis", SQLLocalEatDataInt());
SetLocalInt( oPlayer, "Boulets", SQLLocalEatDataInt());
SetLocalInt( oPlayer, "Avis", SQLLocalEatDataInt());
SetLocalInt( oPlayer, "Damage", SQLLocalEatDataInt());
SetLocalInt( oPlayer, "Guild", SQLLocalEatDataInt());
SetLocalInt( oPlayer, "Guild_rank", SQLLocalEatDataInt());
SetLocalInt( oPlayer, "PK_BAD", SQLLocalEatDataInt());
SetLocalInt( oPlayer, "VOL", SQLLocalEatDataInt());
SetLocalInt( oPlayer, "PKED", SQLLocalEatDataInt());
SetLocalInt( oPlayer, "PK_OK", SQLLocalEatDataInt());
SetLocalInt( oPlayer, "Jailed", SQLLocalEatDataInt());
SetLocalInt( oPlayer, "LastLevelTime", SQLLocalEatDataInt());
SetLocalInt( oPlayer, "LevelCap", SQLLocalEatDataInt());
SetLocalInt( oPlayer, "Level", SQLLocalEatDataInt());
SetLocalInt( oPlayer, "Flags", SQLLocalEatDataInt());

int iXP = SQLLocalEatDataInt();
int Gold = SQLLocalEatDataInt();
SetLocalInt( oPlayer, "PrestigeClass", SQLLocalEatDataInt());

/*
*/
if (iXP>0)
{
int nXP = GetXP(oPlayer);
if (GetXP(oPlayer)!=iXP)
{
if (nXP==0 && iXP>500 && !GetIsDM(oPlayer))
{
BootPC(oPlayer);
pwWriteLog(oPlayer, "LOGIN", "REJET PERSO", "Ancien perso duplique (XP=0)");
return FALSE;
}
ff_SetXP( oPlayer, iXP); // Positionne en meme temps la variable
}
int hasGold = GetGold(oPlayer);
if (hasGold<Gold) // Ajuste l'or dans l'inventaire
{
AssignCommand(oPlayer,GiveGoldToCreature(oPlayer,Gold-hasGold));
DelayCommand(0.5, ReportGold(oPlayer, Gold, hasGold));
}
else
if (hasGold>Gold)
{
AssignCommand(oPlayer,TakeGoldFromCreature(hasGold-Gold, oPlayer, TRUE));
DelayCommand(0.5, ReportGold(oPlayer, Gold, hasGold));
}

if (sRecall=="") // Position du Recall
SQLExecDirect("UPDATE PlayerData SET Recall='"+bmLocationToString(lLocation)+"' WHERE Id=" + sId);

//if (GetGold(oPlayer)!=Gold)
// pwWriteLog2(oPlayer, "GOLD", "devrait avoir "+IntToString(Gold)+", en avait "+IntToString(hasGold)+" et en a maintenant "+IntToString(GetGold(oPlayer)));

}
else
{
ff_SetXP( oPlayer, GetXP(oPlayer), TRUE); // Positionne en meme temps la variable
SetLocalInt( oPlayer, "Gold", GetGold(oPlayer));
}

}
else
bReset = TRUE; // Donnees invalides
}

if (bReset) // INSERT DATA
{
sSQL = "REPLACE INTO PlayerData (Id,Techniques,Position,Level,XP,Gold) VALUES("+sId+",";
InitValues(oPlayer);
sSQL += "'','',"+IntToString(GetHitDice(oPlayer))+","+IntToString(GetXP(oPlayer))+","+IntToString(GetGold(oPlayer))+")";
SQLExecDirect(sSQL);
/*if (iVersion != 3)
{
DelayCommand(0.2,ConvertInventory(oPlayer, "UPDATE idplayer SET Version=3 WHERE Id=" + sId));
}*/
/*if (!HasValidName(oPlayer))
{
SQLExecDirect("UPDATE idplayer SET Ban=1 WHERE Id=" + sId);
SendMessageToAllDMs(GetName(oPlayer)+" (nouveau perso) a ete automatiquement rejete (nom invalide)");
pwWriteLog(oPlayer, "LOGIN", "REJET PERSO", "Nom invalide:"+GetName(oPlayer));
DelayCommand(5.0,SendMessageToPC(oPlayer,ff_Colorize("[r]Votre nom n'est pas correct, refaites un autre personnage en soignant la description et en choisissant bien le nom[y]")));
DelayCommand(80.0,BootPC(oPlayer));
return FALSE;
}*/

if (GetDeity(oPlayer)=="")
if (GetLevelByClass(CLASS_TYPE_CLERIC,oPlayer)>0 || GetLevelByClass(CLASS_TYPE_PALADIN,oPlayer)>0)
{
SQLExecDirect("UPDATE idplayer SET Ban=1 WHERE Id=" + sId);
SendMessageToAllDMs(GetName(oPlayer)+" (nouveau perso) a ete automatiquement rejete (Absence de Dieu pour un pretre ou paladin)");
pwWriteLog(oPlayer, "LOGIN", "REJET PERSO", "Absence de Dieu pour "+GetName(oPlayer));
DelayCommand(5.0,SendMessageToPC(oPlayer,ff_Colorize("[r]Comment voulez-vous jouer un pretre ou un paladin sans avoir un Dieu ?!![y]")));
DelayCommand(80.0,BootPC(oPlayer));
return FALSE;
}
}

if (bReset)
sNewRecord = "CONVERT";
else
if (GetIsDM(oPlayer))
sNewRecord = "DM_IN";
else
if (GetLocalInt(oPlayer,"Damage")>=GetMaxHitPoints(oPlayer))
sNewRecord = "DEAD_IN";
else
sNewRecord = "PC_IN";
pwWriteLogCon(oPlayer, sNewRecord);

SQLExecDirect("UPDATE idplayer SET Actif=1 WHERE Id=" + sId);
}
else // error : No MySQL database available !
{
DeleteLocalString(oPlayer, "PWId");
WriteTimestampedLogEntry("[MySQL] Base de donnees non disponible -> BootPC("+GetName(oPlayer)+")");
DelayCommand(5.0,SendMessageToPC(oPlayer,"Base de donnees non disponible. Desole, le server est actuellement HS"));
DelayCommand(80.0,BootPC(oPlayer));
return FALSE;
}
return TRUE;
}


// These functions are responsible for transporting the various data types back
// and forth to the database.
void SetPersistentString(object oObject, string sVarName, string sValue, int iExpiration=0, string sTable="pwdata")
{
string sPlayer;
string sTag;

if (GetIsPC(oObject))
{
sPlayer = SQLEncodeSpecialChars(GetPCPlayerName(oObject));
sTag = SQLEncodeSpecialChars(GetName(oObject));
}
else
{
sPlayer = "'";
sTag = GetTag(oObject);
}

sVarName = SQLEncodeSpecialChars(sVarName);
sValue = SQLEncodeSpecialChars(sValue);

string sSQL = "REPLACE INTO " + sTable + " (player,tag,name,val,expire) VALUES" +
"('" + sPlayer + "','" + sTag + "','" + sVarName + "','" +
sValue + "'," + IntToString(iExpiration) + ")";
SQLExecDirect(sSQL);
}

string GetPersistentString(object oObject, string sVarName, string sTable="pwdata")
{
string sPlayer;
string sTag;

if (GetIsPC(oObject))
{
sPlayer = SQLEncodeSpecialChars(GetPCPlayerName(oObject));
sTag = SQLEncodeSpecialChars(GetName(oObject));
}
else
{
sPlayer = "''";
sTag = GetTag(oObject);
}

sVarName = SQLEncodeSpecialChars(sVarName);

string sSQL = "SELECT val FROM " + sTable + " WHERE player='" + sPlayer +
"' AND tag='" + sTag + "' AND name='" + sVarName + "'";
return SQLExecAndFetchSingle (sSQL);
}


void SetPersistentInt(object oObject, string sVarName, int iValue, int iExpiration=0, string sTable="pwdata")
{
SetPersistentString(oObject, sVarName, IntToString(iValue), iExpiration, sTable);
}

int GetPersistentInt(object oObject, string sVarName, string sTable="pwdata")
{
return StringToInt(GetPersistentString(oObject, sVarName, sTable));
}

void SetPersistentFloat(object oObject, string sVarName, float fValue, int iExpiration=0, string sTable="pwdata")
{
SetPersistentString(oObject, sVarName, FloatToString(fValue), iExpiration, sTable);
}

float GetPersistentFloat(object oObject, string sVarName, string sTable="pwdata")
{
return StringToFloat(GetPersistentString(oObject, sVarName, sTable));
}

void SetPersistentLocation(object oObject, string sVarName, location lLocation, int iExpiration=0, string sTable="pwdata")
{
SetPersistentString(oObject, sVarName, bmLocationToString(lLocation), iExpiration, sTable);
}

location GetPersistentLocation(object oObject, string sVarName, string sTable="pwdata")
{
return bmStringToLocation(GetPersistentString(oObject, sVarName, sTable));
}

void SetPersistentVector(object oObject, string sVarName, vector vVector, int iExpiration=0, string sTable ="pwdata")
{
SetPersistentString(oObject, sVarName, bmVectorToString(vVector), iExpiration, sTable);
}

vector GetPersistentVector(object oObject, string sVarName, string sTable = "pwdata")
{
return StringToVector(GetPersistentString(oObject, sVarName, sTable));
}

void DeletePersistentVariable(object oObject, string sVarName, string sTable="pwdata")
{
string sPlayer;
string sTag;

if (GetIsPC(oObject))
{
sPlayer = SQLEncodeSpecialChars(GetPCPlayerName(oObject));
sTag = SQLEncodeSpecialChars(GetName(oObject));
}
else
{
sPlayer = "~";
sTag = GetTag(oObject);
}

sVarName = SQLEncodeSpecialChars(sVarName);
string sSQL = "DELETE FROM " + sTable + " WHERE player='" + sPlayer +
"' AND tag='" + sTag + "' AND name='" + sVarName + "'";
SQLExecDirect(sSQL);
}

// Problems can arise with SQL commands if variables or values have single quotes
// in their names. These functions are a replace these quote with the tilde character

string SQLEncodeSpecialChars(string sString)
{
if (FindSubString(sString, "'") == -1) // not found
return sString;

int i;
string sReturn = "";
string sChar;

// Loop over every character and replace special characters
for (i = 0; i < GetStringLength(sString); i++)
{
sChar = GetSubString(sString, i, 1);
if (sChar == "'")
sReturn += "'";
sReturn += sChar;
}
return sReturn;
}

void SetPersistentObject(object oOwner, string sVarName, object oObject, int iExpiration =
0, string sTable = "pwobjdata")
{
string sPlayer;
string sTag;

if (GetIsPC(oOwner))
{
sPlayer = SQLEncodeSpecialChars(GetPCPlayerName(oOwner));
sTag = SQLEncodeSpecialChars(GetName(oOwner));
}
else
{
sPlayer = "~";
sTag = GetTag(oOwner);
}
sVarName = SQLEncodeSpecialChars(sVarName);

string sSQL = "SELECT player FROM " + sTable + " WHERE player='" + sPlayer +
"' AND tag='" + sTag + "' AND name='" + sVarName + "'";
SQLExecDirect(sSQL);

if (SQLFetch() == SQL_SUCCESS)
{
// row exists
sSQL = "UPDATE " + sTable + " SET val=%s,expire=" + IntToString(iExpiration) +
" WHERE player='" + sPlayer + "' AND tag='" + sTag + "' AND name='" + sVarName + "'";
SetLocalString(GetModule(), "NWNX!ODBC!SETSCORCOSQL", sSQL);
StoreCampaignObject ("NWNX", "-", oObject);
}
else
{
// row doesn't exist
sSQL = "INSERT INTO " + sTable + " (player,tag,name,val,expire) VALUES" +
"('" + sPlayer + "','" + sTag + "','" + sVarName + "',%s," + IntToString(iExpiration) + ")";
SetLocalString(GetModule(), "NWNX!ODBC!SETSCORCOSQL", sSQL);
StoreCampaignObject ("NWNX", "-", oObject);
}
}

object GetPersistentObject(object oObject, string sVarName, object oOwner = OBJECT_INVALID, string sTable = "pwobjdata")
{
string sPlayer;
string sTag;
object oModule;

if (GetIsPC(oObject))
{
sPlayer = SQLEncodeSpecialChars(GetPCPlayerName(oObject));
sTag = SQLEncodeSpecialChars(GetName(oObject));
}
else
{
sPlayer = "~";
sTag = GetTag(oObject);
}
sVarName = SQLEncodeSpecialChars(sVarName);

string sSQL = "SELECT val FROM " + sTable + " WHERE player='" + sPlayer +
"' AND tag='" + sTag + "' AND name='" + sVarName + "'";
SetLocalString(GetModule(), "NWNX!ODBC!SETSCORCOSQL", sSQL);

if (!GetIsObjectValid(oOwner))
oOwner = oObject;
return RetrieveCampaignObject ("NWNX", "-", GetLocation(oOwner), oOwner);
}



// Used to remove all items from a persistant chest for a given character
void DeleteAllPersistentObject(object oObject, string sTable = "pwobjdata")
{
string sPlayer;
string sTag;

if (GetIsPC(oObject))
{
sPlayer = SQLEncodeSpecialChars(GetPCPlayerName(oObject));
sTag = SQLEncodeSpecialChars(GetName(oObject));
}
else
{
sPlayer = "~";
sTag = GetTag(oObject);
}
SQLExecDirect("DELETE FROM " + sTable + " WHERE player='" + sPlayer + "' AND tag='" + sTag + "'");
}


/*****************************************
** New FF specific RCO/SCO substitutes **
*****************************************/
// Store an object for that PC on a specific Placable (chest...)
void ff_SetPersistentObject(object oOwner, object oObject, object oPlacable=OBJECT_INVALID, string sTable = "RCO_SCO")
{
string sTag;
string sId = GetLocalString(oOwner, "PWId");
if (GetIsObjectValid(oPlacable))
sTag = GetTag(oPlacable);
else
sTag = "";
SetLocalString(GetModule(), "NWNX!ODBC!SETSCORCOSQL", "INSERT INTO "+sTable+" SET Id="+sId+", tag='"+sTag+"', val=%s");
StoreCampaignObject ("NWNX", "-", oObject);
}

// Retrieve the first object for that PC on a specific Placable (chest...)
object ff_GetPersistentObjectFirst(object oOwner, object oPlacable=OBJECT_INVALID, string sTable = "RCO_SCO")
{
string sTag;
string sId = GetLocalString(oOwner, "PWId");
if (GetIsObjectValid(oPlacable))
sTag = GetTag(oPlacable);
else
sTag = "";
SetLocalString(GetModule(), "NWNX!ODBC!SETSCORCOSQL", "SELECT val FROM "+sTable+" WHERE Id="+sId+" AND tag='"+sTag+"'");

if (GetIsObjectValid(oPlacable))
return RetrieveCampaignObject ("NWNX", "-", GetLocation(oPlacable), oPlacable);
else
return RetrieveCampaignObject ("NWNX", "-", GetLocation(oOwner), oOwner);
}

// Retrieve the next objects ('til return NULL)
object ff_GetPersistentObjectNext(object oOwner, object oPlacable=OBJECT_INVALID)
{
if (GetIsObjectValid(oPlacable))
return RetrieveCampaignObject ("NWNX", "FETCHMODE", GetLocation(oPlacable), oPlacable);
else
return RetrieveCampaignObject ("NWNX", "FETCHMODE", GetLocation(oOwner), oOwner);
}

// Remove all objects associated with that player on a given placable
void ff_CleanPersistentObject(object oOwner, object oPlacable=OBJECT_INVALID, string sTable = "RCO_SCO")
{
string sTag;
string sId = GetLocalString(oOwner, "PWId");
if (GetIsObjectValid(oPlacable))
sTag = GetTag(oPlacable);
else
sTag = "";
SQLExecDirect("DELETE FROM " + sTable + " WHERE Id="+sId+" AND tag='"+sTag+"'");
}


/******************************************
* Those functions need the FF version of *
* NWNX_functions.dll in order to work *
* properly *
******************************************/

// Delete this character file
// Beware, no confirmation is made
void ff_DeleteThisChar(object oPC)
{
if (!GetIsObjectValid(oPC) || !GetIsPC(oPC)) return;
string PCName = GetPCPlayerName(oPC);
string CharName = GetName(oPC);
SQLExecDirect("UPDATE idplayer SET Ban=1 WHERE Id=" + GetLocalString(oPC, "PWId"));
pwWriteLog(oPC,"DELETE",GetPCPlayerName(oPC),GetPCPlayerName(oPC)+" a decide de supprimer definitivement son perso "+GetName(oPC)+" (Id:"+GetLocalString(oPC, "PWId")+")");

ExportSingleCharacter(oPC);
DelayCommand(1.0, BootPC(oPC));
DelayCommand(3.0, SetLocalString(GetModule(), "NWNX!FUNCTIONS!DELETECHAR", PCName+"?"+CharName+"?"));
}


// Returns 1 if Speech DLL is properly working, 0 otherwise
int ff_CheckSpeech()
{
SetLocalString(GetModule(), "NWNX!DLL", "FFSPEECH");
return StringToInt(GetLocalString(GetModule(), "NWNX!DLL"));
}

int ff_CheckLeto()
{
SetLocalString(GetModule(), "NWNX!DLL", "LETO");
return StringToInt(GetLocalString(GetModule(), "NWNX!DLL"));
}

void ff_SetGoldPieceValue(object oObject, int iValue)
{
SetLocalString(oObject, "NWNX!FUNCTIONS!SETGOLDPIECEVALUE", IntToString(iValue));
DeleteLocalString(oObject, "NWNX!FUNCTIONS!SETGOLDPIECEVALUE");
}

void ff_SetName(object oObject, string NewName)
{
SetLocalString(oObject, "NWNX!FUNCTIONS!SETNAME", NewName);
DeleteLocalString(oObject, "NWNX!FUNCTIONS!SETNAME");
}

void ff_SetDescription(object oObject, string NewDescription)
{
SetLocalString(oObject, "NWNX!FUNCTIONS!SETDESCRIPTION", NewDescription);
DeleteLocalString(oObject, "NWNX!FUNCTIONS!SETDESCRIPTION");
}

string ff_GetDescription(object oPC)
{
SetLocalString(oPC, "NWNX!FUNCTIONS!GETDESCRIPTION", "");
return GetLocalString(oPC, "NWNX!FUNCTIONS!GETDESCRIPTION");
}

void ff_SetBodyPart(object oPlayer, int nPart, int nType)
{
SetLocalString(oPlayer,"NWNX!FUNCTIONS!SETBODYPART", IntToString(nPart)+"!"+IntToString(nType));
DeleteLocalString(oPlayer, "NWNX!FUNCTIONS!SETBODYPART");
}

int ff_GetBodyPart(object oPlayer, int nPart)
{
SetLocalString(oPlayer,"NWNX!FUNCTIONS!GETBODYPART", IntToString(nPart));
int iType = StringToInt(GetLocalString(oPlayer, "NWNX!FUNCTIONS!GETBODYPART"));
DeleteLocalString(oPlayer, "NWNX!FUNCTIONS!GETBODYPART");
return iType;
}

void ff_SetLockDC(object oChest, int DC)
{
SetLocalString(oChest, "NWNX!FUNCTIONS!SETLOCKDC", IntToString(DC));
DeleteLocalString(oChest, "NWNX!FUNCTIONS!SETLOCKDC");
}

void ff_SetTag(object oObject, string sValue)
{
SetLocalString(oObject, "NWNX!FUNCTIONS!SETTAG", sValue);
DeleteLocalString(oObject, "NWNX!FUNCTIONS!SETTAG");
}


// Bodypart Variables
const int NWNX_BODYPART_GENDER = 3;
const int NWNX_BODYPART_COLOR_SKIN = 4;
const int NWNX_BODYPART_COLOR_HAIR = 5;
const int NWNX_BODYPART_COLOR_TATTOO_1 = 6;
const int NWNX_BODYPART_COLOR_TATTOO_2 = 7;
const int NWNX_BODYPART_FOOT_R = 8;
const int NWNX_BODYPART_FOOT_L = 9;
const int NWNX_BODYPART_SHIN_R = 10;
const int NWNX_BODYPART_SHIN_L = 11;
const int NWNX_BODYPART_THIGH_L = 12;
const int NWNX_BODYPART_THIGH_R = 13;
const int NWNX_BODYPART_PELVIS = 14;
const int NWNX_BODYPART_TORSO = 15;
const int NWNX_BODYPART_BELT = 16;
const int NWNX_BODYPART_NECK = 17;
const int NWNX_BODYPART_FOREARM_R = 18;
const int NWNX_BODYPART_FOREARM_L = 19;
const int NWNX_BODYPART_BICEP_R = 20;
const int NWNX_BODYPART_BICEP_L = 21;
const int NWNX_BODYPART_SHOULDER_R = 22;
const int NWNX_BODYPART_SHOULDER_L = 23;
const int NWNX_BODYPART_HAND_R = 24;
const int NWNX_BODYPART_HAND_L = 25;
const int NWNX_BODYPART_UNKNOWN = 26;
const int NWNX_BODYPART_HEAD = 27;
const int NWNX_BODYPART_TAIL = 28;
const int NWNX_BODYPART_WING = 29;

void ff_ChangePlayerAppearance(object oPlayer, int nPart, int nType)
{
ff_SetBodyPart(oPlayer, nPart, nType);

int nAppearance = GetAppearanceType(oPlayer);

ApplyEffectToObject(DURATION_TYPE_TEMPORARY,
EffectVisualEffect(VFX_DUR_CUTSCENE_INVISIBILITY), oPlayer, 1.5);

ApplyEffectAtLocation(DURATION_TYPE_INSTANT,
EffectVisualEffect(VFX_IMP_AC_BONUS), GetLocation(oPlayer));
ApplyEffectAtLocation(DURATION_TYPE_INSTANT,
EffectVisualEffect(VFX_IMP_POLYMORPH), GetLocation(oPlayer));

SetCreatureAppearanceType(oPlayer, APPEARANCE_TYPE_SHADOW);
DelayCommand(1.0,
Back to top
View user's profile Send private message
paradogz



Joined: 04 Apr 2012
Posts: 17

PostPosted: Mon Feb 17, 2014 18:25    Post subject: Reply with quote

Up, realised I copied the wrong one, sorry.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    nwnx.org Forum Index -> General Discussion 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