Graal Forums  

Go Back   Graal Forums > Development Forums > Tech Support
FAQ Members List Calendar Search Today's Posts Mark Forums Read

Reply
 
Thread Tools Search this Thread Display Modes
  #1  
Old 07-24-2011, 04:21 AM
ffcmike ffcmike is offline
Banned
Join Date: Jul 2004
Location: London
Posts: 2,029
ffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond repute
Send a message via AIM to ffcmike Send a message via MSN to ffcmike
SQlite and Observer Mode

On Classic I have it so that account data is added to an SQLite database on a player's first login, and if they have already logged in it is then updating the existing data.

For example:

PHP Code:
//Called within onActionPlayerOnline from Control-NPC
public function playerLoggedIn(temp.pl){
  if(
temp.pl.communityname == NULL){
    
temp.cn temp.pl.account;
  }
  else{
    
temp.cn temp.pl.communityname;
  }
  
//The player does not have a flag for being added to the database
  
if(!temp.pl.stat_sqlsetup){
    
temp.query "INSERT INTO tPlayer (account, subscription, lastlogin, gelats, communityname) VALUES ('" temp.pl.account "', '" temp.pl.getSubcription() @ "', " temp.pl.getLoginTime() @ ", " temp.pl.getGelat() @ ", '" temp.cn "')";
    
this.trigger("SQLCommit"temp.query"PlayerStored"temp.pl);
  }
  else{
    
//The player does have a flag for being added to the database
    
temp.query "UPDATE tPlayer SET subscription = '" temp.pl.getSubcription() @ "', lastlogin = " temp.pl.getLoginTime() @ ", gelats = " temp.pl.getGelat() @ ", communityname = '" temp.cn "' WHERE account = '" temp.pl.account "'";
    
this.trigger("SQLCommit"temp.query);
  }

The class script containing "SQLCommit" is as follows:

PHP Code:
function onSQLCommit(temp.querytemp.triggernametemp.param1temp.param2temp.param3){
  
temp.request requestsql(temp.querytrue);
  if(!
temp.request.completed){
    
waitfor(temp.request"onReceiveData"5);
  }
  
//If something goes wrong, such as a failed constraint, the query is logged and no function is triggered
  
if(temp.request.error != NULL){
    
savelog2("log_sql.txt"temp.request.error " : " temp.query);
    echo(
temp.request.error);
    return;
  }
  if(
temp.triggername != NULL){
    
this.trigger(temp.triggernametemp.requesttemp.param1temp.param2temp.param3);
  } 

So in this case, assuming all goes well, this function would be triggered:

PHP Code:
function onPlayerStored(temp.rtemp.pl){
  
temp.pl.stat_sqlsetup true;

The problem I am having is that a small portion of trial accounts are producing an error of "constraint failed", sometimes the problem is that they are added to the database but somehow the flag has not set. Other times the flag is set but they have not been added to the database, and so it fails whenever they are added to a different table containing their primary key of the first table.

As far as I can tell this seems to co-inside with Observer Mode.
Reply With Quote
  #2  
Old 07-24-2011, 05:04 AM
DustyPorViva DustyPorViva is offline
Will work for food. Maybe
DustyPorViva's Avatar
Join Date: Sep 2003
Location: Maryland, USA
Posts: 9,589
DustyPorViva has a reputation beyond reputeDustyPorViva has a reputation beyond reputeDustyPorViva has a reputation beyond reputeDustyPorViva has a reputation beyond reputeDustyPorViva has a reputation beyond reputeDustyPorViva has a reputation beyond reputeDustyPorViva has a reputation beyond reputeDustyPorViva has a reputation beyond reputeDustyPorViva has a reputation beyond reputeDustyPorViva has a reputation beyond reputeDustyPorViva has a reputation beyond repute
Send a message via AIM to DustyPorViva Send a message via MSN to DustyPorViva
Ah, there's your problem. Observer mode.
Reply With Quote
  #3  
Old 07-24-2011, 05:05 AM
Mark Sir Link Mark Sir Link is offline
Kevin Azite
Mark Sir Link's Avatar
Join Date: Sep 2005
Posts: 1,489
Mark Sir Link is just really niceMark Sir Link is just really nice
Send a message via AIM to Mark Sir Link
what are the column constraints for each field? There have been issues on UN where null community names have had issues so you might be better off evaluating
if(temp.pl.communityname.length() > 0)
instead.

You say you have a log what entries are failing so can you post an example of that

EDIT:

posting your function for Player.getSubcription() and Player.getLoginTime() may help as well, if these are in a class than perhaps this is executing before the player joins the class? Or there is an issue with them joining it at all?
Reply With Quote
  #4  
Old 07-24-2011, 05:19 AM
ffcmike ffcmike is offline
Banned
Join Date: Jul 2004
Location: London
Posts: 2,029
ffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond repute
Send a message via AIM to ffcmike Send a message via MSN to ffcmike
One example of an error caused by the account not being added to the database:

Quote:
INSERT INTO tTask (pid, num, complete) VALUES ((SELECT tPlayer.pid FROM tPlayer WHERE tPlayer.account = 'Graal750778'), 0, 1)
The reason this is occurring is because I have a foreign key referring to tPlayer's primary key.
There is also a unique index on pid + num but this isn't the problem.

One example of an error caused by the account already existing within the database:

Quote:
INSERT INTO tPlayer (account, subscription, lastlogin, gelats, communityname) VALUES ('pc:5306287', 'trial', 1311299072, 0, 'guest')
This problem definitely isn't being caused by any of those values being NULL, the other constraint is a unique index on account.

All of the classes are joined and working before this is executed (otherwise this would be producing a function not found error)
Reply With Quote
  #5  
Old 07-24-2011, 09:06 AM
Mark Sir Link Mark Sir Link is offline
Kevin Azite
Mark Sir Link's Avatar
Join Date: Sep 2005
Posts: 1,489
Mark Sir Link is just really niceMark Sir Link is just really nice
Send a message via AIM to Mark Sir Link
the issue with the first one seems to be num being 0, I imagine that is already being used in an entry

not really sure what would cause issues with the flag not being set, although I wonder why you take that approach instead of just checking to see if SELECT * FROM tPlayer WHERE account='pl.account' and checking to see if there is actually an existing row.

UN has had a similar database for about 2 and a half weeks now that hasn't thrown any errors from trials going in and out of observer mode.

The first screenshot has a constraint on account being unique, the 2nd has no constraints on any column



Reply With Quote
  #6  
Old 07-24-2011, 09:06 AM
xXziroXx xXziroXx is offline
Malorian
xXziroXx's Avatar
Join Date: May 2004
Posts: 5,289
xXziroXx has a brilliant futurexXziroXx has a brilliant futurexXziroXx has a brilliant futurexXziroXx has a brilliant futurexXziroXx has a brilliant futurexXziroXx has a brilliant futurexXziroXx has a brilliant future
Maybe you have communityname set to UNIQUE? Would explain why the person with "guest" as community name didn't work.
__________________
Follow my work on social media post-Graal:Updated august 2025.
Reply With Quote
  #7  
Old 07-24-2011, 09:34 AM
cbk1994 cbk1994 is offline
the fake one
cbk1994's Avatar
Join Date: Mar 2003
Location: San Francisco
Posts: 10,718
cbk1994 has a reputation beyond reputecbk1994 has a reputation beyond reputecbk1994 has a reputation beyond reputecbk1994 has a reputation beyond reputecbk1994 has a reputation beyond reputecbk1994 has a reputation beyond reputecbk1994 has a reputation beyond reputecbk1994 has a reputation beyond reputecbk1994 has a reputation beyond reputecbk1994 has a reputation beyond repute
Send a message via AIM to cbk1994
I'm not sure this will fix your problem, but I'd recommend just doing this instead of using a flag:

PHP Code:
INSERT OR REPLACE INTO tPlayer (accountsubscriptionlastlogingelatscommunitynameVALUES ('pc:5306287''trial'13112990720'guest'
If inserting the row would cause a constraint conflict, it deletes the existing row causing the conflict and inserts the row. If there is no conflict, it just inserts the row.

It should get rid of any issues resulting from out-of-sync database/player attributes (e.g. if a player is reset or rolled back).

Note that this will change the rowid for the player's entry, but you should never rely on the rowid. If you specify a PRIMARY KEY column, it probably won't change the rowid.
__________________
Reply With Quote
  #8  
Old 07-24-2011, 09:54 AM
ffcmike ffcmike is offline
Banned
Join Date: Jul 2004
Location: London
Posts: 2,029
ffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond repute
Send a message via AIM to ffcmike Send a message via MSN to ffcmike
Quote:
Originally Posted by xXziroXx View Post
Maybe you have communityname set to UNIQUE? Would explain why the person with "guest" as community name didn't work.
If this was the case this would be occurring for every single guest that logs onto the server, but it is only a small minority.

Quote:
Originally Posted by Mark Sir Link View Post
the issue with the first one seems to be num being 0, I imagine that is already being used in an entry
The unique index is on both num and pid joined together, as in to prevent the same player from having a task entry added twice.
It's definitely not the issue with this, it can just as easily happen with values above 0.

Quote:
Originally Posted by cbk1994 View Post
I'm not sure this will fix your problem, but I'd recommend just doing this instead of using a flag:

PHP Code:
INSERT OR REPLACE INTO tPlayer (accountsubscriptionlastlogingelatscommunitynameVALUES ('pc:5306287''trial'13112990720'guest'
If inserting the row would cause a constraint conflict, it deletes the existing row causing the conflict and inserts the row. If there is no conflict, it just inserts the row.

It should get rid of any issues resulting from out-of-sync database/player attributes (e.g. if a player is reset or rolled back).

Note that this will change the rowid for the player's entry, but you should never rely on the rowid. If you specify a PRIMARY KEY column, it probably won't change the rowid.
I guess that would fix that half of the issue, though that would have the slight inconvenience that you can't see each player in the order they were created when exploring the data.

What I believe might be the problem is that I have the query executed after a trigger, and so by the time onPlayerStored occurs observer mode is already preventing the ability to write flags to the player.
The reason I have it like this is so not to delay any subsequent processes in the Control-NPC's login event where this SQL function is invoked from.
As in:
Control-NPC - SQL.playerLoggedIn();
Control-NPC - Someothersystem.playerLoggedIn();
SQL.onSQLCommit();

As for the issue of players somehow not being stored in the database though I have no idea, no errors are occurring at the time of logging on, I'm only noticing these accounts aren't there due to later tasks failing to add.
Reply With Quote
  #9  
Old 07-24-2011, 10:07 AM
xXziroXx xXziroXx is offline
Malorian
xXziroXx's Avatar
Join Date: May 2004
Posts: 5,289
xXziroXx has a brilliant futurexXziroXx has a brilliant futurexXziroXx has a brilliant futurexXziroXx has a brilliant futurexXziroXx has a brilliant futurexXziroXx has a brilliant futurexXziroXx has a brilliant future
Quote:
Originally Posted by ffcmike View Post
What I believe might be the problem is that I have the query executed after a trigger, and so by the time onPlayerStored occurs observer mode is already preventing the ability to write flags to the player.
I can confirm that, had the same issue on Maloria.
__________________
Follow my work on social media post-Graal:Updated august 2025.
Reply With Quote
  #10  
Old 07-24-2011, 10:12 AM
ffcmike ffcmike is offline
Banned
Join Date: Jul 2004
Location: London
Posts: 2,029
ffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond repute
Send a message via AIM to ffcmike Send a message via MSN to ffcmike
Quote:
Originally Posted by xXziroXx View Post
I can confirm that, had the same issue on Maloria.
Guess I'll have to make SQL the last process within Control-NPC login without a trigger event.
Ideally observer mode would be waiting on such possible triggered events within the login process before kicking in (more ideally would just be removed as it's a pain in the arse to players and developers alike).
Reply With Quote
  #11  
Old 07-24-2011, 10:18 AM
xXziroXx xXziroXx is offline
Malorian
xXziroXx's Avatar
Join Date: May 2004
Posts: 5,289
xXziroXx has a brilliant futurexXziroXx has a brilliant futurexXziroXx has a brilliant futurexXziroXx has a brilliant futurexXziroXx has a brilliant futurexXziroXx has a brilliant futurexXziroXx has a brilliant future
Quote:
Originally Posted by ffcmike View Post
Guess I'll have to make SQL the last process within Control-NPC login without a trigger event.
Ideally observer mode would be waiting on such possible triggered events within the login process before kicking in (more ideally would just be removed as it's a pain in the arse to players and developers alike).
You could just process the SQL part when the player is sent back from observer mode, no? That's what I do at least.
__________________
Follow my work on social media post-Graal:Updated august 2025.
Reply With Quote
  #12  
Old 07-24-2011, 10:22 AM
ffcmike ffcmike is offline
Banned
Join Date: Jul 2004
Location: London
Posts: 2,029
ffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond repute
Send a message via AIM to ffcmike Send a message via MSN to ffcmike
Quote:
Originally Posted by xXziroXx View Post
You could just process the SQL part when the player is sent back from observer mode, no? That's what I do at least.
Good idea, are you checking player.isobserver as a condition to process SQL normally?
Reply With Quote
  #13  
Old 07-24-2011, 10:27 AM
xXziroXx xXziroXx is offline
Malorian
xXziroXx's Avatar
Join Date: May 2004
Posts: 5,289
xXziroXx has a brilliant futurexXziroXx has a brilliant futurexXziroXx has a brilliant futurexXziroXx has a brilliant futurexXziroXx has a brilliant futurexXziroXx has a brilliant futurexXziroXx has a brilliant future
Quote:
Originally Posted by ffcmike View Post
Good idea, are you checking player.isobserver as a condition to process SQL normally?
I do it like this:


PHP Code:
function onActionPlayerOnline()
{
  
// What type is the account?
  
client.upgradeStatus player.upgradestatus;
  
client.communityName = (player.communityname == "" player.account player.communityname);
  
  
// Okay, if it's a trial, let's give some special treatment.
  
if (player.upgradestatus == "trial") {
    
// Just now logging on.
    
if (!player.isLoggedOn)
      return 
initializePlayer();
  }
  else   
    
initializePlayer();
}

function 
onSwitchPlayerToObserver(pl)
  
pl.isLoggedOn true;

function 
onSwitchObserverToPlayer(pl)
  
scheduleevent(1"HandleTrialAccount"pl);

function 
onHandleTrialAccount(pl)
{
  
// Sometimes the player logs off during observer mode but still triggers onSwitchObserverToPlayer
  
if (pl.level.name == "")
    return;
  
  
with (pl)
    
initializePlayer();

EDIT: There's a short delay after onSwitchObserverToPlayer is triggered and when the player isn't observer anymore, hence why I use a scheduleevent.
__________________
Follow my work on social media post-Graal:Updated august 2025.
Reply With Quote
  #14  
Old 07-24-2011, 10:45 AM
ffcmike ffcmike is offline
Banned
Join Date: Jul 2004
Location: London
Posts: 2,029
ffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond repute
Send a message via AIM to ffcmike Send a message via MSN to ffcmike
Quote:
Originally Posted by xXziroXx View Post
I do it like this:


PHP Code:
function onActionPlayerOnline()
{
  
// What type is the account?
  
client.upgradeStatus player.upgradestatus;
  
client.communityName = (player.communityname == "" player.account player.communityname);
  
  
// Okay, if it's a trial, let's give some special treatment.
  
if (player.upgradestatus == "trial") {
    
// Just now logging on.
    
if (!player.isLoggedOn)
      return 
initializePlayer();
  }
  else   
    
initializePlayer();
}

function 
onSwitchPlayerToObserver(pl)
  
pl.isLoggedOn true;

function 
onSwitchObserverToPlayer(pl)
  
scheduleevent(1"HandleTrialAccount"pl);

function 
onHandleTrialAccount(pl)
{
  
// Sometimes the player logs off during observer mode but still triggers onSwitchObserverToPlayer
  
if (pl.level.name == "")
    return;
  
  
with (pl)
    
initializePlayer();

EDIT: There's a short delay after onSwitchObserverToPlayer is triggered and when the player isn't observer anymore, hence why I use a scheduleevent.
I think I'd prefer this if there was a built-in simple way of knowing if somebody was logging on as an observer, for now I'll see how it goes just having SQL occurring within the original event rather than a subsequent trigger.
Reply With Quote
  #15  
Old 07-24-2011, 11:51 AM
Crow Crow is offline
ǝɔɐɹq ʎןɹnɔ
Crow's Avatar
Join Date: Dec 2006
Location: Germany
Posts: 5,153
Crow has a reputation beyond reputeCrow has a reputation beyond reputeCrow has a reputation beyond reputeCrow has a reputation beyond reputeCrow has a reputation beyond reputeCrow has a reputation beyond reputeCrow has a reputation beyond reputeCrow has a reputation beyond reputeCrow has a reputation beyond reputeCrow has a reputation beyond reputeCrow has a reputation beyond repute
Quote:
Originally Posted by ffcmike View Post
I think I'd prefer this if there was a built-in simple way of knowing if somebody was logging on as an observer, for now I'll see how it goes just having SQL occurring within the original event rather than a subsequent trigger.
onSwitchPlayerToObserver() and onSwitchObserverToPlayer() are built-in and should do the trick just fine.
Reply With Quote
  #16  
Old 07-24-2011, 11:58 AM
ffcmike ffcmike is offline
Banned
Join Date: Jul 2004
Location: London
Posts: 2,029
ffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond repute
Send a message via AIM to ffcmike Send a message via MSN to ffcmike
Quote:
Originally Posted by Crow View Post
onSwitchPlayerToObserver() and onSwitchObserverToPlayer() are built-in and should do the trick just fine.
I was referring to something simple/easy from within the onActionPlayerOnline function.

I suppose I could try something such as:

PHP Code:
function onInitialized(){
  
this.observers = new TStaticVar();
}

function 
onSwitchPlayerToObserver(temp.pl){
  
this.observers.(@ temp.pl.account) = true;
}

function 
onSwitchObserverToPlayer(temp.pl){
  
this.observers.(@ temp.pl.account) = false;
  
this.doSQLStuff(temp.pl);
}

function 
onActionPlayerOnline(){
  if(!
this.observers.(@ player.account)){
    
this.doSQLStuff(player);
  }

Under the assumption that onSwitchPlayerToObserver() is occurring before onActionPlayerOnline.
Edit: Tested and it doesn't so scratch that.

Last edited by ffcmike; 07-24-2011 at 12:13 PM..
Reply With Quote
  #17  
Old 07-30-2011, 12:55 AM
ffcmike ffcmike is offline
Banned
Join Date: Jul 2004
Location: London
Posts: 2,029
ffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond repute
Send a message via AIM to ffcmike Send a message via MSN to ffcmike
This issue hasn't been occurring with players logging on for the first time over the last several days so presumably moving the query into the original chain of functions as opposed to a subsequent trigger seems to have fixed it.
Reply With Quote
  #18  
Old 01-05-2012, 02:17 AM
ffcmike ffcmike is offline
Banned
Join Date: Jul 2004
Location: London
Posts: 2,029
ffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond reputeffcmike has a reputation beyond repute
Send a message via AIM to ffcmike Send a message via MSN to ffcmike
Quote:
Originally Posted by ffcmike View Post
This issue hasn't been occurring with players logging on for the first time over the last several days so presumably moving the query into the original chain of functions as opposed to a subsequent trigger seems to have fixed it.
Moving the query into the original function as opposed to a subsequent trigger certainly helped, yet somehow the problem of an observer on their first login not being added to the database, with no error returned from the query, is still happening on the rare occasion.

Whenever I've witnessed it happen at the precise moment, it's always appeared within the playerlist as if the trial player logs in, logs out, and then back in again. This last time however I asked the player if they had logged out in the start level or experienced any problem, they claimed they were logged in the entire time and it ran smoothly.
Reply With Quote
Reply

Thread Tools Search this Thread
Search this Thread:

Advanced Search
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 +2. The time now is 01:38 PM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2026, vBulletin Solutions Inc.
Copyright (C) 1998-2019 Toonslab All Rights Reserved.