Graal Forums  

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

Reply
 
Thread Tools Search this Thread Display Modes
  #1  
Old 08-15-2014, 02:14 AM
scriptless scriptless is offline
Banned
Join Date: Dec 2008
Location: N-Pulse
Posts: 1,412
scriptless is a splendid one to beholdscriptless is a splendid one to beholdscriptless is a splendid one to beholdscriptless is a splendid one to behold
Posessed DBNPC - Please help

Okay I got a DBNPC. I noticed something that I canno't explain. I did not know it was possible and have no idea how to fix this.

I used the following:

PHP Code:
this.("option." player.account) = 0
as well as

PHP Code:
makevar("this.option." player.account) = 0
Problem I am having is no matter which one I use. I get strange behavior. Either the string does get added but then magically disappears when the player logs off, or it appears and stays in the list but then the next time it just creates a second string, and so on. So then I'm left with 2 strings with 100% the same name.

Also,

PHP Code:
temp.pl2 findplayer("bloodpet");
this.("option." "bloodpet") = 1;
if ( 
this.option.bloodpet == null ) echo("null"); 
Outputs:

PHP Code:
null 
All I am trying to accomplish is add a "option.accountNAME = 0" if there is no string nammed option.accountNAME

Last edited by scriptless; 08-15-2014 at 02:32 AM..
Reply With Quote
  #2  
Old 08-15-2014, 03:10 AM
PiX PiX is offline
Registered User
PiX's Avatar
Join Date: Jul 2014
Posts: 9
PiX will become famous soon enough
this.option.(@ player.account) will access a variable within the "option" var, but this.("option." @ player.account) treats "option.<account>" as a variable name itself. That is how you can have two separate data points with similar paths. It also can make the latter unwanted path impossible to access by makevar.
Reply With Quote
  #3  
Old 08-15-2014, 05:11 AM
scriptless scriptless is offline
Banned
Join Date: Dec 2008
Location: N-Pulse
Posts: 1,412
scriptless is a splendid one to beholdscriptless is a splendid one to beholdscriptless is a splendid one to beholdscriptless is a splendid one to behold
Thanks. That helped alot.

Now the only problem I am having with it is the getstringkeys not getting all the flags. Any idea why it might not? I made sure they are all added using the same method.

PHP Code:
  temp.choosefrom getstringkeys("this.option.");
  
temp.options.desc null;

  
// If player is not in the list go ahead and add them anyways
  
if ( this.option.(@player.account) == null ) {
    
this.option.(@player.account) = 0;
  }
  
  for ( 
temp.coption temp.choosefrom ) {
    
// this tells it the option is a playerobject
    // get there account name and head icon
    
if ( player.account != temp.coption ) {
      
temp.pl      findplayer(temp.coption);
      
temp.offline temp.pl == NULL;
      
temp.pl      temp.offline ? new TServerPlayer(@temp.coption) : temp.pl;
      
temp.options.desc.add(temp.pl.account);
    }
  }

  for ( 
temp.pl allplayers ) {
    if ( !(
temp.pl.account in temp.options.desc) ) {
      
// they are RC
      
if ( temp.pl.level != null && temp.pl.account != player.account) {
        
temp.options.desc.add(temp.pl.account);
      }
    }
  }

  
// now send temp.data to be shown in the list :)
  
temp.data temp.options.savevarstoarray(false);
  return 
temp.data
I believe the problem is related to offline players. I could have sworn this was working before for loading head and hair of offline players.

Last edited by scriptless; 08-15-2014 at 05:52 AM..
Reply With Quote
  #4  
Old 08-15-2014, 01:16 PM
PiX PiX is offline
Registered User
PiX's Avatar
Join Date: Jul 2014
Posts: 9
PiX will become famous soon enough
The function getstringkeys will not find a var path if it does not exist. If you are setting your vars to 0, "", {}, or null, the var name and path will not be created because it is equal to null. Try this.option.(@player.account) = 1; or any value not null.
Reply With Quote
  #5  
Old 08-15-2014, 03:25 PM
scriptless scriptless is offline
Banned
Join Date: Dec 2008
Location: N-Pulse
Posts: 1,412
scriptless is a splendid one to beholdscriptless is a splendid one to beholdscriptless is a splendid one to beholdscriptless is a splendid one to behold
Quote:
Originally Posted by PiX View Post
The function getstringkeys will not find a var path if it does not exist. If you are setting your vars to 0, "", {}, or null, the var name and path will not be created because it is equal to null. Try this.option.(@player.account) = 1; or any value not null.
Thanks, I was wondering that. The DBNPC must be removing all flags = 0 when it is updated.
Reply With Quote
  #6  
Old 08-21-2014, 02:33 AM
Restraint Restraint is offline
NaS
Join Date: Jan 2014
Posts: 21
Restraint will become famous soon enough
Have you considered simply using TStaticVars? It will likely simplify what you're trying to do.

You create a TStaticVar as follows:

PHP Code:
  temp.opt this.options = new TStaticVar(); 
Then you can access, say, this.options.(@player.account) like:

PHP Code:
  opt.(@player.account) = ...; 
You could get the "keystrings" via something like:

PHP Code:
  temp.vars opt.getDynamicVarNames(); 
You could toss it to other scripts easily.

You could pass it from clientside to serverside via something like:

PHP Code:
  temp.info opt.saveVarsToArray(false);
  
triggerServer("weapon"this.nameinfo); 
With the serverside looking like:

PHP Code:
function onActionServerside(info) {
  
temp.opts this.options = new TStaticVar();
  
opts.loadVarsFromArray(info);
  ...

It'd generally allow for a lot more of what you're trying to do, since "this.options" is now a path like you want.
Reply With Quote
  #7  
Old 08-21-2014, 07:27 PM
scriptless scriptless is offline
Banned
Join Date: Dec 2008
Location: N-Pulse
Posts: 1,412
scriptless is a splendid one to beholdscriptless is a splendid one to beholdscriptless is a splendid one to beholdscriptless is a splendid one to behold
Kinda what I'm already doing. There's a problem tho. DBNPC seems to not always save flags and they dissapear. Not entirely sure under which circumstances tho. But occasionally I notice some just vanishing. Some people said it happens sometimes when restarting npc server even with the rc save npcs command
Reply With Quote
  #8  
Old 08-21-2014, 08:17 PM
PiX PiX is offline
Registered User
PiX's Avatar
Join Date: Jul 2014
Posts: 9
PiX will become famous soon enough
TStaticVar is normally not used for database flag storage. It is the same as a TGraalVar (every base data type) except as a global reference. This means that the data would not be stored on the database npc, but actually on a global object, which may be deleted after time or server restart. A common technique for storing persistent dynamic vars to a database npc is using a prefix like this.("option_" @ player.account) . You can then find the full list of accounts by doing getstringkeys("this.option_") .
Reply With Quote
  #9  
Old 08-21-2014, 09:31 PM
scriptless scriptless is offline
Banned
Join Date: Dec 2008
Location: N-Pulse
Posts: 1,412
scriptless is a splendid one to beholdscriptless is a splendid one to beholdscriptless is a splendid one to beholdscriptless is a splendid one to behold
I would have to check my script but about the TStaticVar.. but I was meaning I'm using the save art array and loading also the same way. It shows in the flags. Also saves some flags but not every one. I would say I counted 77 saved strings and sadly no way to know for sure how many did not save. Not sure why it would work sometimes... but not all the times..
Reply With Quote
  #10  
Old 08-21-2014, 09:32 PM
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
Quote:
Originally Posted by scriptless View Post
DBNPC seems to not always save flags and they dissapear. Not entirely sure under which circumstances tho. But occasionally I notice some just vanishing. Some people said it happens sometimes when restarting npc server even with the rc save npcs command
I still have no idea why, but it seems that if you do this.trigger('update'); in a DBNPC after saving some value, it won't be lost. We had tons of trouble in the past with DBNPCs rolling back (especially on Era), and this seemed to fix it.

We also noticed that savenpcs seems not effective; we wrote our own that we called before restarting the NPC-server that just called trigger('update') on every DBNPC with much better results -shrug-

Maybe it's just a placebo but I kind of doubt it. I don't know why it works or if it has to be update.
__________________
Reply With Quote
  #11  
Old 08-21-2014, 09:36 PM
scriptless scriptless is offline
Banned
Join Date: Dec 2008
Location: N-Pulse
Posts: 1,412
scriptless is a splendid one to beholdscriptless is a splendid one to beholdscriptless is a splendid one to beholdscriptless is a splendid one to behold
Quote:
Originally Posted by cbk1994 View Post
I still have no idea why, but it seems that if you do this.trigger('update'); in a DBNPC after saving some value, it won't be lost. We had tons of trouble in the past with DBNPCs rolling back (especially on Era), and this seemed to fix it.

We also noticed that savenpcs seems not effective; we wrote our own that we called before restarting the NPC-server that just called trigger('update') on every DBNPC with much better results -shrug-

Maybe it's just a placebo but I kind of doubt it. I don't know why it works or if it has to be update.
Is that trigger available on all dbnpc or is that a custom trigger? Would like to see any documentation on that if possible. I will try it and see if we get any better results maybe. Would you recommend using that trigger every time a new value is added or no?
Reply With Quote
  #12  
Old 08-21-2014, 09:44 PM
Restraint Restraint is offline
NaS
Join Date: Jan 2014
Posts: 21
Restraint will become famous soon enough
Quote:
Originally Posted by PiX View Post
TStaticVar is normally not used for database flag storage. It is the same as a TGraalVar (every base data type) except as a global reference. This means that the data would not be stored on the database npc, but actually on a global object, which may be deleted after time or server restart. A common technique for storing persistent dynamic vars to a database npc is using a prefix like this.("option_" @ player.account) . You can then find the full list of accounts by doing getstringkeys("this.option_") .
This is a terribly ugly way of doing it, as you need to do (" " @ ) every time.

You can do what you're saying via:

this.options.(@player.account)

The advantages of a TStaticVar instead of that are:

1. Easier to send between server and client via savevarstoarray()
2. Easier to write to a file via savevars()
3. Easier to access with smaller variable names and thus cleaner
4?. I would imagine a guess that .getDynamicVarNames() is an O(c) operation, while .getStringKeys() is an O(n) operation.

Also, you claim it's a "global" reference but no more than a DB NPC's variables are.

The advantages outweigh the disadvantages.

However, I am well aware that TStaticVars do not persist for long periods of time. They seem to have some time limit until they are garbage collected. If you're creating a static variable, you can reload it whenever it's garbage collected. If this is a variable that changes rarely but needs to maintain long-term data, saving it to a file is more persistent than BOTH methods described (And a TStaticVar is ideal for that, via .saveVars()).

As Scriptless has stated, even this.'s can have troubles persisting in DB NPCs. If you want true persistence for long-term database usage, I would suggest either:

1. File I/O. This is best method if the files will not change often (since I/O can be laggy). The easiest method for this is, you guessed it, TStaticVars and .savevars

2. SQL DB. This is the best method if the options will be changing frequently, as reading/writing to SQL is less intense than files.
Reply With Quote
  #13  
Old 08-21-2014, 10:10 PM
PiX PiX is offline
Registered User
PiX's Avatar
Join Date: Jul 2014
Posts: 9
PiX will become famous soon enough
Quote:
Originally Posted by scriptless View Post
Is that trigger available on all dbnpc or is that a custom trigger? Would like to see any documentation on that if possible. I will try it and see if we get any better results maybe. Would you recommend using that trigger every time a new value is added or no?
A trigger("update"); can sometimes help with saving dbnpc data, but is normally not needed. It is also sometimes used on the serverside of npc scripts if something is changed on the serverside of it, but does not change on the clientside. Again, normally not needed.
Reply With Quote
  #14  
Old 08-21-2014, 10:16 PM
Jakov_the_Jakovasaur Jakov_the_Jakovasaur is offline
Deleted by Darlene159
Jakov_the_Jakovasaur's Avatar
Join Date: Sep 2013
Location: Deleted by Darlene159
Posts: 353
Jakov_the_Jakovasaur has much to be proud ofJakov_the_Jakovasaur has much to be proud ofJakov_the_Jakovasaur has much to be proud ofJakov_the_Jakovasaur has much to be proud ofJakov_the_Jakovasaur has much to be proud ofJakov_the_Jakovasaur has much to be proud ofJakov_the_Jakovasaur has much to be proud of
hello!

tStaticVars should never be garbage collected for as long as they have an active reference, ive seen them remain for several months and only be destroyed whenever the npc-server is restarted

personally i prefer to store data within an sqlite database, however load the sql data into a tStaticVar cache upon database npc initialization for easier access
__________________
This signature has been deleted by Darlene159.
Reply With Quote
  #15  
Old 08-21-2014, 11:30 PM
scriptless scriptless is offline
Banned
Join Date: Dec 2008
Location: N-Pulse
Posts: 1,412
scriptless is a splendid one to beholdscriptless is a splendid one to beholdscriptless is a splendid one to beholdscriptless is a splendid one to behold
I definately want to move the system to sqlite. But it's currently live on the server and only going to be active another half a week. So it's kinda a bandaid to help make sure it works better till then. I'll try the trigger for now hopefully it buys me time to finish the sql part.

Thanks everyone for the info.
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:58 AM.


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