FiveM update - March 5th, 2017

We have pushed out a set of updates to FiveM lately. The last one unfortunately did not come with a change log entry, so here is a coalesced version of the change log for both.

Summarized changelog

  • Add additional pool entry names to the pool error message.
  • Rename additional leftover project branding of FiveReborn/pΛ to say FiveM.
  • Disconnect from the server when internal code calls OnKillNetwork events.
  • Expose read and readbuffer APIs to citizen:scripting:v8 scripts, for use in updated versions of the C++ script hook porting library.
  • Resource system reworks to support compliance modules.
  • Support for resource compliance. This requires a new version of the server, which is currently in closed testing.
  • Fixes to make the client not hang when joining a game and resources are still being downloaded:
    • Don’t switch rage::fwClipSetManager to network mode (this incurs a blocking load).
    • Disable LOAD_ALL_OBJECTS_NOW until the loading screens have been hidden, usually by spawnmanager causing the player to spawn. This is a workaround for a LoadAllObjectsNow() line in mapmanager.
  • Add a fxd:/ mount to the VFS stack pointing to [AppData]\CitizenFX.
  • Client-side key/value pair storage for resources. This is detailed further below.
  • formats:fraglod tool for the CitizenFX console (FiveM.com), fixing .#ft files that have incoherent LOD levels by cutting off the lower LODs.
  • An internal crash fix in CfxCollection that makes mistyped entries (filetype instead of fileType) not crash.
  • SSC attribute for CitizenFX.Core.UI.ScreenResolution.
  • Fixes for anti-malware software badly hooking NtQueryInformationProcess, causing the ‘crash on loading screen’ seen with AVG/Avast to not occur anymore.
  • Improved crash reporting:
    • SysError calls (fatal errors) now cause the full crash reporting flow to be invoked, fixing the issue with ‘hearing an error sound, the game freezing, but no error popping up’ and improving telemetry.
    • RAGE errors are cleaned up to also follow the above flow.
  • Compatibility fix for a particular version of PLD.asi that doesn’t check return values of fopen before writing to a log file that apparently only serves to glorify the creator of the plugin.
  • Update Mono and change code around to hopefully fix a top crasher in sgen_suspend_thread. This might cause a bunch of weird regressions in CLR functionality.
  • Internal VFS interface improvements.
  • Logging improvements:
    • Hide ‘instrumented function 66/67’ pairs in CitizenFX.log.
    • Don’t print the timestamp in CitizenFX.log in the middle of a line.
    • Make the timestamp in CitizenFX.log relative to creation of the log file, not the OS’s global tick counter.
  • Update V8 for use by compliance code.
  • Improve detection for game-breaking plugins.
  • Delete caches.xml automatically if a framework component file is broken/missing.
  • Potentially improve performance and clean up unneeded use of RTTI in the CitizenFX component model.
  • Revert the entity ownership patch that caused some game crashes and broke SET_*_AS_NO_LONGER_NEEDED, instead just patch out ownership checks directly.
  • Rebrand the pause menu to no longer say ‘Grand Theft Auto Online’ and remove the Facebook link that claimed the user has been banned.
  • Improve main menu performance and add new pages signifying a shift in the project.
  • Fix CLR library updates somehow not having shipped.
  • Revert Rockstar breaking the statue in the Venice Beach area.

Developer information

No wiki as usual, ha! Too busy implementing actual system improvements.

Key/value storage

The key/value storage allows storing arbitrary data on the client side. It can be accessed with standard natives exposed to the CitizenFX scripting component, however no example usage from Lua this time around, no updated natives.lua yet either so you’ll have to guess the definition for now.

The functions are (among others that aren’t exposed as they were ill-designed):

GET_RESOURCE_KVP_INT

Gets a KVP value for the current resource.

Arguments:

  • key (string): the key to fetch

Return value:

An integer containing the integer value stored in the key.

Example:

int kvpValue = GET_RESOURCE_KVP_INT("bananabread");

GET_RESOURCE_KVP_FLOAT

Gets a float KVP value for the current resource.

Arguments:

  • key (string): the key to fetch

Return value:

A float containing the floating-point value stored in the key.

Example:

float kvpValue = GET_RESOURCE_KVP_FLOAT("codfish");

GET_RESOURCE_KVP_STRING

Gets a string KVP value for the current resource.

Arguments:

  • key (string): the key to fetch

Return value:
A string containing the value stored in the key.

Example:

const char* kvpValue = GET_RESOURCE_KVP_STRING("mollis");

SET_RESOURCE_KVP

Sets a string KVP value for the current resource.

Arguments:

  • key (string): the key to set
  • value (string): the value to write

Return value:
None.

Example:

SET_RESOURCE_KVP("mollis", "vesuvius citrate");

SET_RESOURCE_KVP_INT

Sets an integer KVP value for the current resource.

Arguments:

  • key (string): the key to set
  • value (int): the value to write

Return value:
None.

Example:

int lickMy = 42;
SET_RESOURCE_KVP_INT("bananabread", lickMy);

SET_RESOURCE_KVP_FLOAT

Sets a float KVP value for the current resource.

Arguments:

  • key (string): the key to set
  • value (float): the value to write

Return value:
None.

Example:

float curseBuster = 0xBC * 2.5f;
SET_RESOURCE_KVP_INT("codfish", curseBuster);

DELETE_RESOURCE_KVP

Removes a KVP value.

Arguments:

  • key (string): the key to delete

Return value:
None.

Example:

DELETE_RESOURCE_KVP("liberty_city"); // it's over!

START_FIND_KVP

Opens a find handle for scanning KVP entries that begin with a specific prefix.

Arguments:

  • prefix (string): a prefix match

Return value:
A KVP find handle to use with FIND_KVP and close with END_FIND_KVP once completed. -1 if unlucky.

Example:

SET_RESOURCE_KVP("mollis:2", "should be taken with alcohol");
SET_RESOURCE_KVP("mollis:1", "vesuvius citrate");
SET_RESOURCE_KVP("mollis:manufacturer", "Betta Pharmaceuticals");

int kvpHandle = START_FIND_KVP("mollis:");

if (kvpHandle != -1)
{
  const char* key = nullptr;

  do
  {
    key = FIND_KVP(kvpHandle);
    
    if (key)
    {
      trace("%s: %s\n", key, GET_RESOURCE_KVP_STRING(key));
    }
  } while (key);
  
  END_FIND_KVP(kvpHandle);
}

Potential output:

mollis:1: vesuvius citrate
mollis:2: should be taken with alcohol
mollis:manufacturer: Betta Pharmaceuticals

FIND_KVP

Returns the current key a KVP find handle is pointing to, then increments the cursor.

Arguments:

  • handle (int): the KVP find handle returned from START_FIND_KVP.

Return value:
A string containing the current key, or null if the end of the iteration has been reached.

Example:
See START_FIND_KVP.

END_FIND_KVP

Closes a KVP find handle.

Arguments:

  • handle (int): the KVP find handle returned from START_FIND_KVP.

Return value:
None.

Example:
See START_FIND_KVP.

Compliance

Compliance is currently not exposed to end users, and will be exposed some time after the completion of the closed beta test.

A compliance snakeoil API exists to allow compliance resources to obfuscate objects differently.

SET_SNAKEOIL_FOR_ENTRY

Sets the snakeoil script file for a file entry in the current resource, passing additional metadata.

Arguments:

  • name (string): the entry name to apply snakeoil to, for instance stat_hilberty01.ydr.
  • path (string): the path in the existing resource to the snakeoil script file.
  • extradata (encoded JSON): extra data to pass to the script.

Return value:
A boolean indicating success.

Example:

function SetSnakeoilForEntry(name, path, data)
	Citizen.InvokeNative(0xa7dd3209, name, path, data)
end

SetSnakeoilForEntry('stat_hilberty01.ydr', 'snakeoil.js', '{"liberty": "city"}')
SetSnakeoilForEntry('liberty_pedestal01.ytd', 'snakeoil.js', '{"liberty": "island"}')

Snakeoil script files

The snakeoil script file implements the snakeoil algorithm used for the resource. An example is as follows:

class oil {
	initialize(data) {
		print("initializing snakeoil on: " + data.liberty);
	}

	// to resynchronize a cipher with an offset in the file
	seek(off) {
		print("seeking: " + off);
	}

	// currently, argument is an ArrayBuffer, return value the same
	// do note the argument's lifetime exists only for the duration of the function call!
	decrypt(data) {
		print("decrypting: " + data.byteLength + " bytes");

		return data;
	}
}

// the global 'snakeoil' object contains a factory returning a snakeoil instance.
snakeoil = () => new oil();

Future plans

None are known so far, recent changes have caused some plans for an internal reorganization of the project. We still set out to complete the goals we described earlier, but the exact time frame for this is sadly unknown.

We have also adopted :snail: (from Emoji One 2) as our official project mascot! :snail:

10 Likes

Could you guys please address the repeated crashing issues within the game?

“We have also adopted :snail:” XD
Great work! Keep it up :slight_smile:

If you’d post actual crash IDs for these crashes, sure. The most common crash (other than those caused by modifications) has hopefully been fixed already by this update.

I posted a crash ID on one of my posts.

If you mean this post, then, yes, this is supposed to be fixed by this entry in the changelog:

It says in the little paragraph about Script Hook comming, is that in the works?

scripthook already works? You thinking of Rage hook?

For some reason, this update has broken the Added vehicles that i have on my server, i attempt to spawn a vehicle named ‘police5’ and the vehicle model will be invalid even though i have all the vehicle.meta coded right and they worked on a previous version of the update, if the is something i need to add in or change, please respond or PM me, thank you.

this update has problem with waypoint ? cz i dont see waypoint for e second or next waypint set …

somtime some of my lua script work and somtime not work … what happen with this update ?

Some very nice changes in there as well as gracefully received bugfixes. Thanks for the hard work & taking the time to write this whopping changelog!

3 Likes