Array problem
#1

I have a problem with arrays...

I have a really big array new Friends[2000][2000][friendsEnum];
But when i put it like this, It takes WAAAAY to long to compile and I end up with a 126MB file (WAAY HUGE)
Any workaround for this because I tried new Friends[][][friendsEnum]; and it just crashed PAWN
Reply
#2

Yeah obviously that's going to be huge... That's an array with "2000*2000*sizeof(friendsEnum)" slots.

Why would you need an array that large? Explain a bit more.
Reply
#3

Yeah, I know but I can think of any other way to do this
Anyways...
Im using a MySQL saving system and naturally all users have their ID in the database
Now with this array, I can do Friends[ID OF USER IN DB][ID OF USER IN DB][isFriend] and that way check if the users are friends or Friends[ID OF USER IN DB][ID OF USER IN DB][online] and check if the users friend is online and such
Reply
#4

My guess is, you plan to have a maximum of 2000 accounts on your server and keep the entire friendlist for all players loaded at all times?

What happens if you get 10000 accounts?
You would need to increase the array to Friends[10000][10000][isFriend].

There is no need to let the server hold all player's friends in memory all the time.
Most of the time, not all of your players will be online, so why keep all that data loaded?



Just set a maximum limit to everyone's friendlist, say 100 friends per player.
Then you can use PlayerData[playerid][FriendList][100].

When the player logs on, search the database for all his friends and load them in this enum field.
With 50 players online at a time, you only need 50 * 100 ID's in the server memory.

Even if you allow 2000 friends per player and you allow 100 players online at a time, it's still alot smaller (2000 * 100) compared to 2000*2000.

You can even use a loop to check if the loaded friend-ID's are online or offline when displaying the list in a dialog or something.
Reply
#5

Yeah the [2000][2000] was just for the test version and to see how pawn will react to 2000*2000
Il try to come up with something with that method
Thanks
Reply
#6

Or save the player's friends in the database on the player's row, like "1|2|3|4|5|6". And split it to get a player's friends.

Or create a new table, and save all the friends of players in there. And have it save in multiple rows. For example:

sql_idsql_id_userfriends
111|2|3|4|5|6 (up to 30-50)
217|8|9|10|11 (up to 30-50)
321|2|3|4|5 (up to 30-50)
4112|13|14|15 (up to 30-50)
I'd go with the second option.

You'll just do:
Quote:

format(query, sizeof(query), "SELECT `friends` FROM `friends` WHERE `sql_id_user` = '%d' AND `sql_id` > '%d'", aUserInfo[playerid][user_info_sql_id], pLastFriendsSQLID[playerid]);

Quite simple. Just separate the list in pages. And ta da! You're done.
Reply
#7

It's bad practise to put multiple values into one field in a database.
It's a database, not a textfile (where you probably want to do this).

Just make each player-player friendship as a separate row in the table.
You only need 2 columns: PlayerID and FriendID.
You can even set both columns as primary key, so if you try to add the same friendship twice, the query will fail as it won't allow 2 rows with the exact same data (would be ridiculous as well).
And it's also alot easier to remove one player from his friendlist, you only need to delete the required row and it's done.
Reply
#8

Quote:
Originally Posted by AmigaBlizzard
Посмотреть сообщение
It's bad practise to put multiple values into one field in a database.
It's a database, not a textfile (where you probably want to do this).

Just make each player-player friendship as a separate row in the table.
You only need 2 columns: PlayerID and FriendID.
You can even set both columns as primary key, so if you try to add the same friendship twice, the query will fail as it won't allow 2 rows with the exact same data (would be ridiculous as well).
And it's also alot easier to remove one player from his friendlist, you only need to delete the required row and it's done.
Not at all. It's bad practice to say "practice" wrong.

All you do is retrieve ONE field, and split it with sscanf or a custom split function.

But yeah, it's bad in this case since you'll have to retrieve the whole field then split it, just to check whether a player is friends with another player. It's just an example on how to create a list of friends without having the ability to "unfriend" someone.
Reply
#9

My bad, English isn't my native language

Also, when you have only 2 columns as I said above, you can save some rows as your player can be in the first column and in the second.

When being friends, it's normal the relationship works the other way around as well.

So there is no need to have this in your table somewhere:
PlayerID --- FriendID
5 ---------- 17
17 --------- 5

This would make player 5 friends with player 17 and also the other way around.
One row would suffice.

You could retrieve a player's entire friendlist using:
"SELECT * FROM friendlist WHERE PlayerID = %d OR FriendID = %d", PlayerData[playerid][SQLID], PlayerData[playerid][SQLID]

And when loading the data, you simply check if the FriendID is your own PlayerID or not.
If it isn't your own ID, then store the FriendID.
If it is your own ID, use the PlayerID from the result as friendID.


Example:
PlayerID -- FriendID
5 -------- 17
8 -------- 19
1 -------- 24
17 ------- 3
17 ------- 29
31 ------- 17

You're PlayerID 17 and your friends would be 5, 3, 29 and 31.

The amount of rows returned is automatically the amount of friends you have.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)