Today I learned - Share your newly found knowledge!

Today I learned that you cannot re-texture or re-color animated objects, which sucks beyond belief. They will just become invisible. Today I also learned that the script I wrote to compensate for this causes a 36 MB/h download rate for a single object, which makes it practically unusable. So yeah, today was not a very good day.
Reply

Today I learned, How to make your own Call of Duty server from scratch. (MySQL and SQLite)
Reply

Quote:
Originally Posted by ShadyEG
Посмотреть сообщение
Today I learned, How to make your own Call of Duty server from scratch. (MySQL and SQLite)
Okay, posts like these are starting to get on my nerves. MySQL is a database system, it has nothing to do with the core of the gamemode. This is like saying "Today I learned how to cook a perfect steak. (Salt and pepper)"

Not trying to bring you down, I just needed to vent
Reply

Well, Today I learned a lil' about scripting gamemodes in Shoebill.
Reply

Today I learned, you can make Call of Duty with SQLite and MySQL
Reply

Today I learned that
Quote:
Originally Posted by Vince
Посмотреть сообщение
YSI is notorious for a lot of compiler hacking and lots and lots of macros, many of which recursive. The compiler has to do multiple rounds to parse all this hacked stuff which makes it incredibly slow. I would suggest including only the stuff that you actually need. If you only require foreach then only include y_iterate, for example.
Reply

Quote:
Originally Posted by Whitetiger
Посмотреть сообщение
til

pawn Код:
print("\a");
Gives an audible sound from the server console. Admittedly, not the most useful discovery...
That's actually very useful, also works with the bell ascii.
pawn Код:
printf("%c", 7);
Reply

Today I learned by trial-error, how to generate a unique UUID ( User Unique ID ) with a prefix!
Код:
stock GenerateUUID() {
 new UUID[9];
 new SALT_LENGTH = 6;
 new SALT_PREFIX[] = "LRP"; // Change to whatever you want (3 letters only)
 new SALT[6];

 while(SALT_LENGTH--) {
  SALT[SALT_LENGTH] = ( random(2) ? (random(26) + (random(2) + 'A')) : (random(10) + '0') );
 }
	
 format(UUID, sizeof(UUID), "%s%s", SALT_PREFIX, SALT);
 return UUID;
}
Credits to RyDeR` for the original function "randomString".
Reply

Quote:
Originally Posted by thewildlima
Посмотреть сообщение
Today I learned by trial-error, how to generate a unique UUID ( User Unique ID ) with a prefix!
Код:
stock GenerateUUID() {
 new UUID[9];
 new SALT_LENGTH = 6;
 new SALT_PREFIX[] = "LRP"; // Change to whatever you want (3 letters only)
 new SALT[6];

 while(SALT_LENGTH--) {
  SALT[SALT_LENGTH] = ( random(2) ? (random(26) + (random(2) + 'A')) : (random(10) + '0') );
 }
	
 format(UUID, sizeof(UUID), "%s%s", SALT_PREFIX, SALT);
 return UUID;
}
Credits to RyDeR` for the original function "randomString".
That won't be unique. That code will only have 1040 possible outcomes (2 * 26 * 2 * 10), which isn't a lot.
Reply

Quote:
Originally Posted by Crayder
Посмотреть сообщение
That won't be unique. That code will only have 1040 possible outcomes (2 * 26 * 2 * 10), which isn't a lot.
Hmm, thanks, what could i do to improve it, so it would be really unique? Increase string length?
Reply

Quote:
Originally Posted by thewildlima
Посмотреть сообщение
Hmm, thanks, what could i do to improve it, so it would be really unique? Increase string length?
It doesn't matter how long your string is because there is a possibility that the exact same string is generated
To create an unique key you would need to save all existing keys and check if the new key is unused

Although the easiest method would be to use a counter which increased by one each time
For that you only need to save the counter

If I am not mistaken the possibilities are not 1040, they are 37 (different characters) ^ 5 (string length) = 69,343,957
5 because your UUID array is only 9 cells long, and therefor cutting of the last character of your SALT
Reply

Quote:
Originally Posted by Crayder
Посмотреть сообщение
That won't be unique. That code will only have 1040 possible outcomes (2 * 26 * 2 * 10), which isn't a lot.
You're calculating it wrong.

Assuming that
Код:
SALT[SALT_LENGTH] = ( random(2) ? (random(26) + 'A') : (random(10) + '0') );
(removed the "random(2) + 'A'" since it doesn't really makes sense to me):
http://www.wolframalpha.com/input/?i...r+i%3D1+to+n-1

So your UUID has 1458599936 possible combinations. As much as it looks like, it isn't. I'd recommend you increase the length from 6 to something between 20 and 24 in order to always generate really unique UID's.

Here's an improved (and fixed; you forgot null termination on strings) version:
Код:
GenerateUuid()
{
    static const rand_len = 22;
    static const prefix[] = "LRP";
    new uuid[sizeof(prefix) + rand_len] = prefix;
    new rand_str[rand_len + 1];
    
    for (new i; i != rand_len; i++)
    {
        uuid[i + sizeof(prefix) - 1] = 
            random(2) ? (random(26) + 'A') : (random(10) + '0');
    }
    
    return uuid;
}
Beware that this function might get slower the higher rand_len is (no guarantees on performance here though).
Reply

If there's any randomness involved then it can never be truly unique. The chance of a match is extremely small but it is still there nevertheless. Assuming MySQL, let the database generate the salt. Use an inline variable in the query so you don't have to fetch it to store it elsewhere.
PHP код:
INSERT INTO `UserVALUES (NULL'name''email'UNIX_TIMESTAMP(), SHA1(CONCAT('password', @salt := SHA1(UUID()))), @salt); 
Looks complicated, but once written shouldn't have to be changed ever again.
Reply

Today I learned that a pointer can be realized by doing
PHP код:
new pointer[][] = {{}}; 
The funny thing is that pawn accepts empty arrays
And if you declare an array without value or with arrays with different sizes the second bounds check isn't present

As example a function to print out the code segment
PHP код:
stock printCOD() {
    new 
size;
    new 
address;
    new 
pointer[][] = {{}};
    
// Gets the start and the size of the COD segment
    #emit lctrl 0
    #emit move.alt
    #emit lctrl 1
    #emit sub.alt
    #emit stor.s.pri address
    #emit neg
    #emit shr.c.pri 2
    #emit stor.s.pri size
    
SetPointer(pointeraddress);
    for(new 
isize; ++i) {
        
printf("%d"pointer[0][i]);
    }

Reply

Quote:
Originally Posted by maddinat0r
Посмотреть сообщение
You're calculating it wrong.

Assuming that
Код:
SALT[SALT_LENGTH] = ( random(2) ? (random(26) + 'A') : (random(10) + '0') );
(removed the "random(2) + 'A'" since it doesn't really makes sense to me):
http://www.wolframalpha.com/input/?i...r+i%3D1+to+n-1

So your UUID has 1458599936 possible combinations. As much as it looks like, it isn't. I'd recommend you increase the length from 6 to something between 20 and 24 in order to always generate really unique UID's.

Here's an improved (and fixed; you forgot null termination on strings) version:
Код:
GenerateUuid()
{
    static const rand_len = 22;
    static const prefix[] = "LRP";
    new uuid[sizeof(prefix) + rand_len] = prefix;
    new rand_str[rand_len + 1];
    
    for (new i; i != rand_len; i++)
    {
        uuid[i + sizeof(prefix) - 1] = 
            random(2) ? (random(26) + 'A') : (random(10) + '0');
    }
    
    return uuid;
}
Beware that this function might get slower the higher rand_len is (no guarantees on performance here though).
If it comes to jobs that really require uniqueness (database ids or filenames that directly cause errors, or scripting stuff that would cause semantic errors for duplicate IDs. Hash salts wouldnt require true uniqueness) you wont get around checking for the uniqueness. Even if the chance for a duplicate ID is microscopically small, it might happen at some time, and then it quite probably causes annoying bugs that are hard to track or might even ruin your data. So you should always countercheck the other IDs to completely prevent duplicates.
You also dont need that long IDs then, which saves generation time and hdd/ram space. You should aim for a good balance between the absolute maximum of different IDs and the time it needs to check for duplicates. Just like good code should aim for 100% reliability, not just for 99,99999999%.
Reply

Код:
        some3dtext = CreateDynamic3DTextLabel("hi", -1, 0.0, 0.0, 0.0, 0.0, 0);
	DestroyDynamic3DTextLabel(some3dtext);
	
	printf("%i", some3dtext); //prints 1
	
	if (IsValidDynamic3DTextLabel(some3dtext ))
	{
		printf("first is valid..."); //this doesn't print
	}
	
	some3dtext  = INVALID_3DTEXT_ID;
	
	printf("%i", some3dtext); //prints 65535
	
	if (IsValidDynamic3DTextLabel(some3dtext))
	{
		printf("invalid is valid..."); //this doesn't print
	}
So I learned that I don't have to reset them by equalizing them with INVALID_3DTEXT_ID since both methods make them invalid. Silly perhaps but had to be sure so wanted to test. :P
Reply

Today I learned that - if in pawn.cfg set flag -d(1-3) , the compiler will add "break" assembler instruction every time when it found ";" in script .
Reply

Quote:
Originally Posted by ISmokezU
Посмотреть сообщение
Guessing.

PHP код:
aDG_Max_Warn[10] = {12, ..........}; 
Prints : 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ?

So what if i want it to print to 100, 100 dots?

TIL

https://en.wikipedia.org/wiki/Modulo_operation
Funny how you could think about that. Imagine a vector of size 1000+ . It was a pretty unexpected question and a smart observation for his example. I guess that this made me smile more than it should.

---------------------------------------

Quote:
Originally Posted by Hansrutger
Посмотреть сообщение
Код:
        some3dtext = CreateDynamic3DTextLabel("hi", -1, 0.0, 0.0, 0.0, 0.0, 0);
	DestroyDynamic3DTextLabel(some3dtext);
	
	printf("%i", some3dtext); //prints 1
	
	if (IsValidDynamic3DTextLabel(some3dtext ))
	{
		printf("first is valid..."); //this doesn't print
	}
	
	some3dtext  = INVALID_3DTEXT_ID;
	
	printf("%i", some3dtext); //prints 65535
	
	if (IsValidDynamic3DTextLabel(some3dtext))
	{
		printf("invalid is valid..."); //this doesn't print
	}
So I learned that I don't have to reset them by equalizing them with INVALID_3DTEXT_ID since both methods make them invalid. Silly perhaps but had to be sure so wanted to test. :P
No ! That's very bad ! IDs aren't unique in a server session, the same ID can be used infinite times. The only IDs unique in a server session are timers (I hope I didn't miss other elements). They start at 1 and don't have any limit.

If you won't reset the variable, something like this could happen:
PHP код:
new Text3D:vartext;
public 
OnGameModeInit( )
{
    
vartext Create3DTextLabel( ... ); // textlabel ID 0
    
Create3DTextLabel( ... ); // textlabel ID 1
    
Create3DTextLabel( ... ); // textlabel ID 2
}
public 
OnPlayerPickUpPickupplayeridpickupid )
{
    if( 
IsValid3DTextLabelvartext ) ) // let's say you want it to be deleted when any pickup is picked up
        
Delete3DTextLabelvartext ); // textlabel ID 0 is now deleted, so it isn't valid
}
// later
Create3DTextLabel( ... ); // because textlabel ID 0 is no longer valid, and it is the first free ID, this 3DText will be created with ID 0.
// you probably don't want it to be deleted when any player pick any pickup, but it will be deleted, because ID 0, which is
// stored in "vartext" is now valid (so IsValid3DTextLabel will return 1 for textlabel ID 0) 
I recommend you to reset to -1 every element(timer [even if IDs are unique]/vehicles/objects/etc)-storing variable after deletion. You won't need to call functions like IsValid3DTextLabel (functions are slower than variables) anymore, only "variable != -1" . Or, yet better, instead of -1 use the correct definitions: INVALID_VEHICLE_ID, INVALID_ACTOR_ID, INVALID_OBJECT_ID, etc. . If there's no "invalid" definition you could just use -1, to be sure, as all of them are starting at 0 or 1 ( https://sampwiki.blast.hk/wiki/Starting_IDs ).

I actually had problems some years ago because I didn't reset variables after destroying. Random elements were deleted when they shouldn't (they can even change properties, for example you could add components to the wrong vehicle, or setting bad objects positions and so on. Every function that can apply to an element ID). Reset variables ! Otherwise it will give you headaches in the future.
Reply

Код:
printf("Inventory %s", B);

format(X, 32, "%s", A);
format(Y, 15, "%s", B);
format(Z, 25, "%s", C);

printf("Dropping %s", Y);


Forgetting to initialize variable Y as a char array can be giving very weird, yet interesting, result lol. Because Y was an integer, it continued to copy C's string into Y for some reason lel.
Reply

Код:
SomeFunction(maybe, some, parameters);
{
   SendClientMessage(maybe, COLOR_SOME, "Text");
}
Can make your compiler go bananas and you end up spending some great time on finding what the heck is wrong since the compiler just stops working. Eventually you see that you added an unnecessary semicolon to the function. Sadly this has happened to me in the past but I had forgotten what it was, luckily it didn't take way too long time figuring it out since I had been compiling frequently!

Protip: Compile as much as you can! :P
Reply


Forum Jump:


Users browsing this thread: 8 Guest(s)