Jump to content

Recommended Posts

Posted

[quote name='Rendril' date='29 October 2009 - 05:48 PM' timestamp='1256831311' post='46066']
I think you will have to remove the text manually for now.
Remember to do the appropriate garbage removal on keys and storages you don't need.
[/quote]
how can you remove a key you gave to a player, without him going through my script?

  • Root Admin
Posted

[quote name='Rendril' date='01 November 2009 - 03:28 PM' timestamp='1257089324' post='46295']
To remove a key use mds_take_rpqc_keys("key name")
He won't have access to your script.
[/quote]

so this will remove what key? all keys of that name? from everyone?

Posted

Yes chew.
And rendril, I think no one means, can we remove keys without needing the player to go to a clickable where we store the key taking script. If they need to go to a certain place where we store the script to take keys, then it will take extra work to tell them to go there. While taking keys can be done for those who finished the quest by just adding the script there, key cleanup for those who never finished it will be a bit problematic..

Posted (edited)

[quote name='Chewett' date='01 November 2009 - 05:33 PM' timestamp='1257089639' post='46296']
so this will remove what key? all keys of that name? from everyone?
[/quote]

There are no "all keys of that name", you can only have one instance of a specific key, addign more of the same name does nothing (it overwrites it thus eliminating duplicates)
And only the person accessing the clickable can have keys removed or given.

[quote name='Udgard' date='01 November 2009 - 05:46 PM' timestamp='1257090383' post='46297']
Yes chew.
And rendril, I think no one means, can we remove keys without needing the player to go to a clickable where we store the key taking script. If they need to go to a certain place where we store the script to take keys, then it will take extra work to tell them to go there. While taking keys can be done for those who finished the quest by just adding the script there, key cleanup for those who never finished it will be a bit problematic..
[/quote]

The player must be there in order for their keys to be accessed, that is why there is no ID parameter for the key functions.
You do not need a dedicated clickable for them to go to simply to cleanup keys, just implement it in the last leg fo your quest.
As for people who do not finish the quest, you are correct, there is no way to guaretntee that the keys will be remvoed at present. For example, they might never return, or might not do a quest of yours again, and even if they did you would have to remember to remove very ancient keys...

Edited by Rendril
  • Root Admin
Posted

You need some way of displaying all Keys you have assigned and being able to remove all keys you assigned from everyone. That would solve the Quest cleanup problem

Posted (edited)

[quote name='Chewett' date='01 November 2009 - 05:14 PM' timestamp='1257095682' post='46310']
You need some way of displaying all Keys you have assigned and being able to remove all keys you assigned from everyone. That would solve the Quest cleanup problem
[/quote]


Yes I am interested in a function something like :

mds_setkey_player();

which would return a list of all players who have had that key activated. This would allow me to keep progress of my quest to see how many people have completed each leg and also allow a quick and easy "garbage disposal" of old keys when the quest is done by sending the list of active players to the remove key routine.

Does such a function exist yet?

Cutler

Edited by cutler121
Posted

actually there was a function to see if a person had my keys before... it came up in the private player logs.. it was how i knew if someone had access to my cave. Will there be a similar feature where we can input the keys we use so we can see if a player has our key?

Posted

I posted elsewhere abotu the way the keys get stored.
I do not think storing the editor info is a feasible solution right now.
In concept it is simple enough:
Take the one-dimensional array and convert it into a two-dimensional array of depth 2 or more.
But there are 32k living accoutns on the server.
To go through the entire player database and restructure the key settings would take a substantial amount of time.
Remember the time it took just to delete the inactive accounts?

But now, what if something goes wrong? What if the array conversion algorithm hits a snag on an unexpected key input?
Easily avoidable perhaps but it adds tiem to the conversion.

Now once the keys have been completely restructured what happens to the keys that already exist, who will be the editor?
Not the player-defined keys but the keys which let you move around MD.
I suspect Mur created a global has_key function on the locations but is he didn't, every item would have to be redone.
That means access to Loreroot main entrance, the hidden entrance (again), Sage's Keep, exit from tutorial mode to name but a few.


My suggestion is to prefix the editor name/id to the key server-side thereby killing 2 birds with one stone, no need to self prefix your keys (although it would still be advised) and it allows an editor to search for the keys he created.
You will however lose cross-key sharing. To rememdy this, there can be a decided shared key function which reuqests the sharer ID as a parameter.

---

There will not be an option to select ALL keys you have given because of the way the clickables work. They can only manipulate the keys of the player accessing them at the specific time.
If you are very interested in having such a list, make one yourself and keep it in a storage.

What many are not considering is that the storage can perform the same function as the keys, in fact I don't think we really need keys because the storange can handle it all.

RJ, there is still such a function, have a look at the manual for [url="http://magicduel.invisionzone.com/topic/5498-key-control/"]key control[/url]
The fucntion you are refering to is mds_has_rpcq_keys()

Posted

I think there is a less invasive method to do this.

I assume keys are stored as follows: every player object in the list of players, has a list of keys (string constants).
It is feasible to make a list of keys (string constants) and for every key have a list of players ids (integer constants). This list can safely be generated from the first list (the first list is not altered), although the query might take a long time, but the process need only be done once.

A new function could be made, returning a list of player ids that have a certain key.
list mds_who_has_key(const String "key");

If you know the keyname, you can then print a list of people that have that key. You do not have to be the one who made/gave the key. Downside is this doubles the amount of variables stored for a single key. It would help [post='46236']the cleanup process[/post] though.

Posted

The keys are an array of strings held for each player object.
Storing an integer constant for the editor is feasible.
I like it as a solution, but is it workable with the current system?

The clickable has access to only the player accessing it. To have a function asking for "all players" means querying the database.
If quertying the databse is acceptable (it puts a greater load on the server for MySQL overhead) then it could be done.

Posted

[quote name='Rendril' date='02 November 2009 - 02:31 PM' timestamp='1257168708' post='46396']
The keys are an array of strings held for each player object.
Storing an integer constant for the editor is feasible.
I like it as a solution, but is it workable with the current system?

The clickable has access to only the player accessing it. To have a function asking for "all players" means querying the database.
If quertying the databse is acceptable (it puts a greater load on the server for MySQL overhead) then it could be done.
[/quote]
I assume the player objects themselves are stored in an array or another list type. Each player object has an array of keys. (I seriously doubt this is a traditional fixed length array, more likely a linked list.)
Essentially: array_of_players[uid].array_of_keys[i]
For different uids, the i-th key is not necessarily the same string constant. This means that mds_has_rpcq_keys("keyname") actually does (c++ style):

for( i = 0; i < array_of_players[uid].array_of_keys.length() && !found; i++){
[indent]if( array_of_players[uid].array_of_keys[i] == "keyname" )
[indent] found = true;[/indent][/indent]}
return found;

A hashmap of keynames list_of_players_with_key["keyname"].list_of_uids[i] can be made. Each element of the hashmap is an object containing an array of uids (integer constants, references to player objects would work too of course). To output all players that have a certain key:

for( i = 0; i < list_of_players_with_key["keyname"].list_of_uids.length(); i++)
[indent] std::cout << list_of_players_with_key["keyname"].list_of_uids[i];[/indent]
Generating the hashmap from the player array is a trivial double loop. After it is generated, every time a key is given or taken, a modification in both 2d arrays should occur simultaneously, keeping both structures in sync. Both of these operations are single loops, with the length of the loop depending on number of keys a player has and number of players that have a key respectively. This is also where having useless keys increases cpu time.

Posted (edited)

You put forth a powerful solution but there is a big flaw, your assumption.

With the way you have proposed it, there would be a player array with 30k entries.
Even if we assume a mere 1kb per player info (counting name, keys, id etc) it would take 30mb at minimum. That is almost a percent of the server's total RAM, and only a minimal estimate. If 100 clickables were ot be accessed concurrenmtly that's the whole server taken down because it's trying to hold 300k rows in memory.
Please correct me if I have misundertood what you meant.

I'm guessing you were refering to the array of players who have the key.
Anyway, there is no such player array.
There is but a single player object.

The player object is select roughly in this way
[code]SELECT * FROM players WHERE id = $id LIMIT 1[/code]
This is a big generalisation on what the query loks like just to give an idea.

Now, it will return a key array (an array of string) in the player object.
In c++ style the has_keys() function does roughly this, where key is the string for the key and keys is the array of them.
[code]if(keys[key] != null)
return true;
else
return false;
[/code]
I know this is c++ code which wouldn't work, php supports associative arrays where you can define custom named indexes. The keys are stored that way in order to eliminate duplicates.

Edited by Rendril
Posted (edited)

[quote name='Rendril' date='02 November 2009 - 05:40 PM' timestamp='1257180036' post='46410']
You put forth a powerful solution but there is a big flaw, your assumption.

With the way you have proposed it, there would be a player array with 30k entries.
Even if we assume a mere 1kb per player info (counting name, keys, id etc) it would take 30mb at minimum. That is almost a percent of the server's total RAM, and only a minimal estimate. If 100 clickables were ot be accessed concurrenmtly that's the whole server taken down because it's trying to hold 300k rows in memory.
Please correct me if I have misundertood what you meant.[/quote]
Why would you put the same array into the ram multiple times? The one exception to this is multithreading. But even then you only need one copy to read from and you cannot have multiple copies to write to, lest you wish to risk data going out of sync.
If there are 30k players, there will be 30k player objects. These objects hold things like keys, name, creatures owned stats etc. The key part isn't taking up the majority of that 1kb though.

[quote]I'm guessing you were refering to the array of players who have the key.
Anyway, there is no such player array.
There is but a single player object.[/quote]
That's why I said such an array should be created. There is no need to store all player data in it though. primary index is keyname, second column contains arrays of player ids, not player objects. Once you have the player id, you can retrieve the player object from the existing player array.

[quote]The player object is select roughly in this way
[code]SELECT * FROM players WHERE id = $id LIMIT 1[/code]
This is a big generalisation on what the query looks like just to give an idea.

Now, it will return a key array (an array of string) in the player object.
In c++ style the has_keys() function does roughly this, where key is the string for the key and keys is the array of them.
[code]if(keys[key] != null)
return true;
else
return false;
[/code]
I know this is c++ code which wouldn't work, php supports associative arrays where you can define custom named indexes. The keys are stored that way in order to eliminate duplicates.
[/quote]

In similar fashion, with a second table for keys:
[code]SELECT * FROM keytable WHERE key = '$key' LIMIT 1[/code]
Will return an array of integers. You can use the same associative array type to check whether a certain player(uid) has said key, or you could print out all elements the array has and thus know which players have the key. If you want to transform uids into names, you can use the original table at the cost of an extra query.

Edited by Kafuuka
Posted (edited)

[quote name='Kafuuka' date='02 November 2009 - 07:23 PM' timestamp='1257182610' post='46414']
Why would you put the same array into the ram multiple times? The one exception to this is multithreading. But even then you only need one copy to read from and you cannot have multiple copies to write to, lest you wish to risk data going out of sync.
If there are 30k players, there will be 30k player objects. These objects hold things like keys, name, creatures owned stats etc. The key part isn't taking up the majority of that 1kb though.[/quote]

Each clickable being accessed would needs its own copy of the array. It means every load would have to regenerate the same array.
PHP has a way of making globally available variables but I don't think in the way we need it.


[quote name='Kafuuka' date='02 November 2009 - 07:23 PM' timestamp='1257182610' post='46414']
That's why I said such an array should be created. There is no need to store all player data in it though. primary index is keyname, second column contains arrays of player ids, not player objects. Once you have the player id, you can retrieve the player object from the existing player array.
[/quote]
This is could be done. In the clickable access it performs an extra SELECT to pick up what players hold the key. But what keys would be selected, all those created by the edior?
How would cross-item key sharing be done?

[quote name='Kafuuka' date='02 November 2009 - 07:23 PM' timestamp='1257182610' post='46414']
In similar fashion, with a second table for keys:
[code]SELECT * FROM keytable WHERE key = '$key' LIMIT 1[/code]
Will return an array of integers. You can use the same associative array type to check whether a certain player(uid) has said key, or you could print out all elements the array has and thus know which players have the key. If you want to transform uids into names, you can use the original table at the cost of an extra query.
[/quote]
That is the problem, there is [b]no key table[/b].

Keys are stored as a serialized array in the player table.

Edited by Rendril
Posted

[quote name='Rendril' date='02 November 2009 - 06:56 PM' timestamp='1257184570' post='46420']
That is the problem, there is [b]no key table[/b].

Keys are stored as a serialized array in the player table.
[/quote]
Then [b]make one[/b], and keep it in sync. Obviously only Mur could actually make one, but that goes for the delete button too.

Posted

It's not a simple case of just adding a table for them.
As I addressed earlier, in the worst case it means every scene in MD needs ot be edited.
While I doubt this will be the case, it is still a big change.

If there is enough of an outcry for a dedicated key table, Mur might make one.

I am not convinced of a table being needed for this, the solutions cost as much as the leakage if not more. The best is perhaps the multidimensional array with ID integer stored alongside it's key name string sibling.

Posted

It goes beyond clickables.
The scenes themselves are affected by keys.
If you have the key for Golemus, you can use the gate to get in.
The key for Loreroot is what makes sure the guards are not there.
I think that being out of tutorial mode is managed by a key too.

Posted

the Tutorial has a lot of keys on it.....each time you pass a ''checkpoint'' in the tutorial, you get a key to be able to continue. There are numerous "game keys".

Posted

Same question applies: is there a single function for adding/removing a key or is it hardcoded for every single key? It's hard to believe someone would actually do that.

Posted

[quote name='Rendril' date='02 November 2009 - 01:12 PM' timestamp='1257160360' post='46376']
If you are very interested in having such a list, make one yourself and keep it in a storage.What many are not considering is that the storage can perform the same function as the keys, in fact I don't think we really need keys because the storage can handle it all.
[/quote]
OK, give me an example of the storage thing. Remember, i want a storage across clickables, across "players that click on clickables".

Other problems would be :
- what about the "noob scripters" giving keys before learning to delete them.
- how can you make this storage protected from others ?



[quote name='Kafuuka' date='02 November 2009 - 07:23 PM' timestamp='1257182610' post='46414']
Once you have the player id, you can retrieve the player object from the existing player array.In similar fashion, with a second table for keys:[code]SELECT * FROM keytable WHERE key = '$key' LIMIT 1[/code]Will return an array of integers. You can use the same associative array type to check whether a certain player(uid) has said key, or you could print out all elements the array has and thus know which players have the key. If you want to transform uids into names, you can use the original table at the cost of an extra query.
[/quote]
considering that a tables can be created I suggest a structure like
user_keys (uid, key_id, last_access_timestamp, system_key_flag)
indexes :
-> (uid, key_id) -> unique
-> (key_id, uid) -> to have double access to keys, starting from user and from key
Even if the "system_key_flag" will be redundant, it will help the purge.
"last_access_timestamp" is there specially for purge but it can be also be available as read-only value so that we know when it was given.

keys (key_id, owner_id, key_name, timestamp)
indexes :
-> (key_id) for unique column & fast access on values
-> (owner_id, key_name) for fast list / filter of keys by owner & uniq values
-> (timestamp) to make a cleanup of a table that will reach a few millions or records


[quote name='Rendril' date='02 November 2009 - 09:41 PM' timestamp='1257190894' post='46431']
It's not a simple case of just adding a table for them.As I addressed earlier, in the worst case it means every scene in MD needs ot be edited.While I doubt this will be the case, it is still a big change.If there is enough of an outcry for a dedicated key table, Mur might make one.I am not convinced of a table being needed for this, the solutions cost as much as the leakage if not more. The best is perhaps the multidimensional array with ID integer stored alongside it's key name string sibling.
[/quote]
Rendril: nobody said that it will be easy, but what do you suggest ? keeping track of the keys it is a huge task that could require huge resources. And ... when do you think that the array is too big ? It already has 1k for each player (as you state) and most of if from names of keys instead of ids (redundancy). Not to mention that some of them were introduced by hand, witch mean that there are mistakes.

Remeber that the MDStore and WPStore both could be changed to keys, along with a lot more features.
Also, for programming part ... the migration to separate table can be prepared by creating functions that check for keys. So, changing the function will have an effect on ALL locations where keys are stored.

[quote name='Rendril' date='03 November 2009 - 01:31 AM' timestamp='1257204708' post='46443']
It goes beyond clickables.The scenes themselves are affected by keys.If you have the key for Golemus, you can use the gate to get in.The key for Loreroot is what makes sure the guards are not there.I think that being out of tutorial mode is managed by a key too.
[/quote]

So ? it will take some time, but it should be changed.
Fixing keys took a lot of time, why would "takes a lot of time" mean "not to be done" ?

Posted

[quote name='Kafuuka' date='03 November 2009 - 12:48 PM' timestamp='1257245289' post='46481']
Same question applies: is there a single function for adding/removing a key or is it hardcoded for every single key? It's hard to believe someone would actually do that.
[/quote]
I suspect there is a single function for it, but each scene could be checking for a key in its specific way.
I am not saying this is what it does, just a possibility.
I genuinely hope it is being checked in the preloader queries.

[quote name='No one' date='03 November 2009 - 01:41 PM' timestamp='1257248465' post='46485']
OK, give me an example of the storage thing. Remember, i want a storage across clickables, across "players that click on clickables".

Other problems would be :
- what about the "noob scripters" giving keys before learning to delete them.
- how can you make this storage protected from others ?
[/quote]

As far as I know, the cross-user storages are not finished yet.
Here is an example that uses all object, this user.
If you want it with all users, you will have to manage the user id's manually, it might be easier with just the ucrrent methods.
[code]
//get the stored "keys"
retrieve(@vk);

//make a new blank array if it doens't already exist
if(@vk == null)
@vk = array();

//giving the user a "key"
@vk[] = "my-key-name";

//checking if user has the "key"
if(in_array("my-key-name", @vk))
echo "you have the key!";

//save the "keys" back in storage
store(@vk);
[/code]

[quote name='No one' date='03 November 2009 - 01:41 PM' timestamp='1257248465' post='46485']
considering that a tables can be created I suggest a structure like
user_keys (uid, key_id, last_access_timestamp, system_key_flag)
indexes :
-> (uid, key_id) -> unique
-> (key_id, uid) -> to have double access to keys, starting from user and from key
Even if the "system_key_flag" will be redundant, it will help the purge.
"last_access_timestamp" is there specially for purge but it can be also be available as read-only value so that we know when it was given.

keys (key_id, owner_id, key_name, timestamp)
indexes :
-> (key_id) for unique column & fast access on values
-> (owner_id, key_name) for fast list / filter of keys by owner & uniq values
-> (timestamp) to make a cleanup of a table that will reach a few millions or records
[/quote]


[quote name='No one' date='03 November 2009 - 01:41 PM' timestamp='1257248465' post='46485']
Rendril: nobody said that it will be easy, but what do you suggest ? keeping track of the keys it is a huge task that could require huge resources. And ... when do you think that the array is too big ? It already has 1k for each player (as you state) and most of if from names of keys instead of ids (redundancy). Not to mention that some of them were introduced by hand, witch mean that there are mistakes.
[/quote]
I suggest the same method that you and Kafuuka are advocating. However, unless you can show a huge difference in costs I do not think it will be done.

[quote name='No one' date='03 November 2009 - 01:41 PM' timestamp='1257248465' post='46485']
Remeber that the MDStore and WPStore both could be changed to keys, along with a lot more features.
Also, for programming part ... the migration to separate table can be prepared by creating functions that check for keys. So, changing the function will have an effect on ALL locations where keys are stored.
[/quote]
I believe the MDStore and WPStore already work on keys.
We are assuming there is a global key-checking function. If there is, great. If not, it means a massive game overhaul.

[quote name='No one' date='03 November 2009 - 01:41 PM' timestamp='1257248465' post='46485']
So ? it will take some time, but it should be changed.
Fixing keys took a lot of time, why would "takes a lot of time" mean "not to be done" ?
[/quote]

That's not what I meant, I'm saying the tradeoff isn't good enough.
Please correct me if I am wrong in this estimation:

Most key lengths will not exceed 30 characters nor will they fall below 10 characters (taking prefix length into account) so we have an average of about 20 characters for a key, that means 20 bytes.

In the current method that means it is storing twice that due to the asoicative indexing, thus 40 bytes.

Can you explain why you gave 2 tables? I'm not sure why both are needed.
The way I see it these are the fields that would be needed:
key_id (long - 4 bytes)
user_id (long - 4 bytes)
editor_id (long - 4 bytes)
key_name (string - 20 bytes average from above)
last_access_timestamp (long - 4 bytes )
system_key_flag (boolean - 1 bit)

Usage per row = 36 bytes (I hve omitted the 1-bit boolean)

So, 40 bytes compared to 36 bytes.
This is a pretty big increase, 10% is no small matter.
In 1mb of keys we save 100kb.
But this is without taking into consideration the MySQL overhead, which does not come cheaply.
MySQL does its own indexing and storing of additional metadata tables for faster querying. This alone makes the table method cost more than the redundant key sotrage.
Correct me if I am wrong, but I think additional tables and indexing take much more than the 4 bytes saved.


Please don't misunderstand. I am in favour of the method you suggest.
I just haven't seen sufficient cause to warrant a massive migration.
If you can provide conclusive reasoning for how it is remarkably better, we can take it to Mur.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Forum Statistics

    17.5k
    Total Topics
    182.1k
    Total Posts
  • Recently Browsing

    • No registered users viewing this page.
  • Upcoming Events

    No upcoming events found
  • Recent Event Reviews

×
×
  • Create New...