1
0
mirror of https://github.com/citizenfx/cfx-server-data.git synced 2025-01-08 22:22:57 +08:00

work on __resource -> fxmanifest and RDR compatibility

This commit is contained in:
astatine 2019-12-10 10:57:04 +01:00
parent 4fff23e2ff
commit 5ca4612547
31 changed files with 602 additions and 76 deletions

View File

@ -1,3 +1,6 @@
resource_type 'map' { gameTypes = { ['basic-gamemode'] = true } } resource_type 'map' { gameTypes = { ['basic-gamemode'] = true } }
map 'map.lua' map 'map.lua'
fx_version 'adamant'
game 'gta5'

View File

@ -1,3 +1,6 @@
resource_type 'map' { gameTypes = { ['basic-gamemode'] = true } } resource_type 'map' { gameTypes = { ['basic-gamemode'] = true } }
map 'map.lua' map 'map.lua'
fx_version 'adamant'
game 'gta5'

View File

@ -0,0 +1,8 @@
resource_type 'map' { gameTypes = { ['basic-gamemode'] = true } }
map 'map.lua'
fx_version 'adamant'
game 'rdr3'
rdr3_warning 'I acknowledge that this is a prerelease build of RedM, and I am aware my resources *will* become incompatible once RedM ships.'

View File

@ -0,0 +1,2 @@
spawnpoint 'player_three' { x = -262.849, y = 793.404, z = 118.087 }
spawnpoint 'player_zero' { x = -262.849, y = 793.404, z = 118.087 }

View File

@ -1,3 +0,0 @@
resource_type 'gametype' { name = 'Freeroam' }
client_script 'basic_client.lua'

View File

@ -0,0 +1,6 @@
resource_type 'gametype' { name = 'Freeroam' }
client_script 'basic_client.lua'
game 'common'
fx_version 'adamant'

View File

@ -8,3 +8,6 @@ chat_theme 'gtao' {
default = '<b>{0}</b><span>{1}</span>' default = '<b>{0}</b><span>{1}</span>'
} }
} }
game 'common'
fx_version 'adamant'

View File

@ -3,10 +3,10 @@
} }
.chat-window { .chat-window {
--size: calc((((2.7vw / 1.77777) * 1.2)) * 6); --size: calc(((2.7vh * 1.2)) * 6);
position: absolute; position: absolute;
right: calc(1.56vw); right: calc(2.77vh);
top: calc(50% - (var(--size) / 2)); top: calc(50% - (var(--size) / 2));
height: var(--size) !important; height: var(--size) !important;
@ -33,10 +33,10 @@
font-family: Font2, sans-serif; font-family: Font2, sans-serif;
color: #fff; color: #fff;
font-size: calc(1.8vw / 1.77777); /* 13px in 720p, calc'd by width */ font-size: calc(1.8vh); /* 13px in 720p, calc'd by width */
filter: url(#svgDropShadowFilter); filter: url(#svgDropShadowFilter);
line-height: calc((2.7vw / 1.77777) * 1.2); line-height: calc(2.7vh * 1.2);
margin-bottom: 0; margin-bottom: 0;
} }
@ -55,7 +55,7 @@
line-height: 1; line-height: 1;
font-size: calc(2.7vw / 1.77777); /* 13px in 720p, calc'd by width */ font-size: calc(2.7vh);
} }
.msg > span > span > span { .msg > span > span > span {
@ -69,8 +69,8 @@
.chat-input { .chat-input {
position: absolute; position: absolute;
right: calc(1.56vw); right: calc(2.77vh);
bottom: calc(1.56vw); bottom: calc(2.77vh);
background: inherit !important; background: inherit !important;
@ -86,7 +86,7 @@
.chat-input > div { .chat-input > div {
background-color: rgba(0, 0, 0, .6); background-color: rgba(0, 0, 0, .6);
padding: calc(0.15625vw / 2); padding: calc(0.28vh / 2);
} }
.chat-input .prefix { .chat-input .prefix {
@ -97,20 +97,32 @@
.chat-input > div + div { .chat-input > div + div {
position: absolute; position: absolute;
bottom: calc(1.65vh + 0.15625vw + 0.15625vw + 0.15625vw + (0.15625vw / 2)); bottom: calc(1.65vh + 0.28vh + 0.28vh + 0.28vh + (0.28vh / 2));
width: 99.6%; width: 99.6%;
text-align: left; text-align: left;
} }
.suggestions { .suggestions {
border: calc(0.15625vw / 2) solid rgba(180, 180, 180, .6); border: calc(0.28vh / 2) solid rgba(180, 180, 180, .6);
background: transparent; background: transparent;
} }
textarea { textarea {
background: transparent; background: transparent;
border: calc(0.15625vw / 2) solid rgba(180, 180, 180, .6); border: calc(0.28vh / 2) solid rgba(180, 180, 180, .6);
padding: calc(0.15625vw / 2); padding: calc(0.28vh / 2);
padding-left: calc(3.5% + (0.15625vw / 2)); padding-left: calc(3.5% + (0.28vh / 2));
}
@media screen and (min-aspect-ratio: 21/9) {
.chat-window, .chat-input {
right: calc(12.8vw);
}
}
@media screen and (min-aspect-ratio: 32/9) {
.chat-window, .chat-input {
right: calc(25vw);
}
} }

View File

@ -1,3 +1,5 @@
local isRDR = not TerraingridActivate and true or false
local chatInputActive = false local chatInputActive = false
local chatInputActivating = false local chatInputActivating = false
local chatHidden = true local chatHidden = true
@ -194,7 +196,7 @@ Citizen.CreateThread(function()
Wait(0) Wait(0)
if not chatInputActive then if not chatInputActive then
if IsControlPressed(0, 245) --[[ INPUT_MP_TEXT_CHAT_ALL ]] then if IsControlPressed(0, isRDR and `INPUT_MP_TEXT_CHAT_ALL` or 245) --[[ INPUT_MP_TEXT_CHAT_ALL ]] then
chatInputActive = true chatInputActive = true
chatInputActivating = true chatInputActivating = true
@ -205,7 +207,7 @@ Citizen.CreateThread(function()
end end
if chatInputActivating then if chatInputActivating then
if not IsControlPressed(0, 245) then if not IsControlPressed(0, isRDR and `INPUT_MP_TEXT_CHAT_ALL` or 245) then
SetNuiFocus(true) SetNuiFocus(true)
chatInputActivating = false chatInputActivating = false

View File

@ -24,3 +24,7 @@ files {
'html/vendor/fonts/LatoBold.woff2', 'html/vendor/fonts/LatoBold.woff2',
'html/vendor/fonts/LatoBold2.woff2', 'html/vendor/fonts/LatoBold2.woff2',
} }
fx_version 'adamant'
games { 'rdr3', 'gta5' }
rdr3_warning 'I acknowledge that this is a prerelease build of RedM, and I am aware my resources *will* become incompatible once RedM ships.'

View File

@ -24,4 +24,5 @@ files {
} }
-- support the latest resource manifest -- support the latest resource manifest
resource_manifest_version '05cfa83c-a124-4cfa-a768-c24a5811d8f9' fx_version 'adamant'
game 'gta5'

View File

@ -8,7 +8,8 @@ server_scripts {
"mapmanager_server.lua" "mapmanager_server.lua"
} }
resource_manifest_version "77731fab-63ca-442c-a67b-abc70f28dfa5" fx_version 'adamant'
games { 'gta5', 'rdr3' }
server_export "getCurrentGameType" server_export "getCurrentGameType"
server_export "getCurrentMap" server_export "getCurrentMap"
@ -17,3 +18,5 @@ server_export "changeMap"
server_export "doesMapSupportGameType" server_export "doesMapSupportGameType"
server_export "getMaps" server_export "getMaps"
server_export "roundEnded" server_export "roundEnded"
rdr3_warning 'I acknowledge that this is a prerelease build of RedM, and I am aware my resources *will* become incompatible once RedM ships.'

View File

@ -62,6 +62,10 @@ AddEventHandler('onResourceStop', function(res)
end) end)
AddEventHandler('getMapDirectives', function(add) AddEventHandler('getMapDirectives', function(add)
if not CreateScriptVehicleGenerator then
return
end
add('vehicle_generator', function(state, name) add('vehicle_generator', function(state, name)
return function(opts) return function(opts)
local x, y, z, heading local x, y, z, heading

View File

@ -8,3 +8,8 @@ export 'loadSpawns'
export 'setAutoSpawn' export 'setAutoSpawn'
export 'setAutoSpawnCallback' export 'setAutoSpawnCallback'
export 'forceRespawn' export 'forceRespawn'
fx_version 'adamant'
games { 'rdr3', 'gta5' }
rdr3_warning 'I acknowledge that this is a prerelease build of RedM, and I am aware my resources *will* become incompatible once RedM ships.'

View File

@ -187,6 +187,10 @@ local function freezePlayer(id, freeze)
end end
function loadScene(x, y, z) function loadScene(x, y, z)
if not NewLoadSceneStart then
return
end
NewLoadSceneStart(x, y, z, 0.0, 0.0, 0.0, 20.0, 0) NewLoadSceneStart(x, y, z, 0.0, 0.0, 0.0, 20.0, 0)
while IsNewLoadSceneActive() do while IsNewLoadSceneActive() do
@ -258,14 +262,18 @@ function spawnPlayer(spawnIdx, cb)
-- release the player model -- release the player model
SetModelAsNoLongerNeeded(spawn.model) SetModelAsNoLongerNeeded(spawn.model)
-- RDR3 player model bits
if N_0x283978a15512b2fe then
N_0x283978a15512b2fe(PlayerPedId(), true)
end
end end
-- preload collisions for the spawnpoint -- preload collisions for the spawnpoint
RequestCollisionAtCoord(spawn.x, spawn.y, spawn.z) RequestCollisionAtCoord(spawn.x, spawn.y, spawn.z)
-- spawn the player -- spawn the player
--ResurrectNetworkPlayer(GetPlayerId(), spawn.x, spawn.y, spawn.z, spawn.heading) local ped = PlayerPedId()
local ped = GetPlayerPed(-1)
-- V requires setting coords as well -- V requires setting coords as well
SetEntityCoordsNoOffset(ped, spawn.x, spawn.y, spawn.z, false, false, false, true) SetEntityCoordsNoOffset(ped, spawn.x, spawn.y, spawn.z, false, false, false, true)
@ -328,7 +336,7 @@ Citizen.CreateThread(function()
while true do while true do
Citizen.Wait(50) Citizen.Wait(50)
local playerPed = GetPlayerPed(-1) local playerPed = PlayerPedId()
if playerPed and playerPed ~= -1 then if playerPed and playerPed ~= -1 then
-- check if we want to autospawn -- check if we want to autospawn

View File

@ -1,3 +0,0 @@
dependency 'yarn'
--server_only 'yes'
server_script 'webpack_builder.js'

View File

@ -0,0 +1,5 @@
dependency 'yarn'
server_script 'webpack_builder.js'
fx_version 'adamant'
game 'common'

View File

@ -1,2 +0,0 @@
--server_only 'yes'
server_script 'yarn_builder.js'

View File

@ -0,0 +1,4 @@
fx_version 'adamant'
game 'common'
server_script 'yarn_builder.js'

View File

@ -41,7 +41,7 @@ const yarnBuildTask = {
currentBuildingModule = resourceName; currentBuildingModule = resourceName;
const process = child_process.fork( const process = child_process.fork(
require.resolve('./yarn_cli.js'), require.resolve('./yarn_cli.js'),
['install'], ['install', '--ignore-scripts'],
{ {
cwd: path.resolve(GetResourcePath(resourceName)) cwd: path.resolve(GetResourcePath(resourceName))
}); });

View File

@ -1,2 +0,0 @@
client_script 'client.lua'
server_script 'server.lua'

View File

@ -0,0 +1,6 @@
client_script 'client.lua'
server_script 'server.lua'
fx_version 'adamant'
games { 'gta5', 'rdr3' }
rdr3_warning 'I acknowledge that this is a prerelease build of RedM, and I am aware my resources *will* become incompatible once RedM ships.'

View File

@ -1,2 +0,0 @@
client_script 'rconlog_client.lua'
server_script 'rconlog_server.lua'

View File

@ -0,0 +1,7 @@
client_script 'rconlog_client.lua'
server_script 'rconlog_server.lua'
fx_version 'adamant'
games { 'gta5', 'rdr3' }
rdr3_warning 'I acknowledge that this is a prerelease build of RedM, and I am aware my resources *will* become incompatible once RedM ships.'

View File

@ -16,3 +16,6 @@ files {
'html/res/futurastd-medium.ttf', 'html/res/futurastd-medium.ttf',
'html/res/futurastd-medium.svg', 'html/res/futurastd-medium.svg',
} }
fx_version 'adamant'
game 'gta5'

View File

@ -8,7 +8,7 @@ Citizen.CreateThread(function()
if IsControlPressed(0, 27)--[[ INPUT_PHONE ]] then if IsControlPressed(0, 27)--[[ INPUT_PHONE ]] then
if not listOn then if not listOn then
local players = {} local players = {}
ptable = GetPlayers() local ptable = GetActivePlayers()
for _, i in ipairs(ptable) do for _, i in ipairs(ptable) do
local wantedLevel = GetPlayerWantedLevel(i) local wantedLevel = GetPlayerWantedLevel(i)
r, g, b = GetPlayerRgbColour(i) r, g, b = GetPlayerRgbColour(i)
@ -35,18 +35,6 @@ Citizen.CreateThread(function()
end end
end) end)
function GetPlayers()
local players = {}
for i = 0, 31 do
if NetworkIsPlayerActive(i) then
table.insert(players, i)
end
end
return players
end
function sanitize(txt) function sanitize(txt)
local replacements = { local replacements = {
['&' ] = '&amp;', ['&' ] = '&amp;',

View File

@ -0,0 +1,2 @@
node_modules/
yarn.lock

View File

@ -0,0 +1,8 @@
fx_version 'adamant'
game 'common'
dependencies {
'yarn'
}
server_script 'sm_server.js'

View File

@ -0,0 +1,6 @@
{
"private": true,
"dependencies": {
"@citizenfx/protobufjs": "6.8.8"
}
}

View File

@ -0,0 +1,169 @@
syntax = "proto3";
package rline;
message RpcErrorData {
string ErrorCodeString = 1;
int32 ErrorCode = 2;
string DomainString = 3;
int32 DomainCode = 4;
bytes DataEx = 5;
};
message RpcError {
int32 ErrorCode = 1;
string ErrorMessage = 2;
RpcErrorData Data = 3;
};
message RpcHeader {
string RequestId = 1;
string MethodName = 2;
RpcError Error = 3;
string srcTid = 4;
};
message RpcMessage {
RpcHeader Header = 1;
bytes Content = 2;
};
message RpcResponseContainer {
bytes Content = 1;
};
message RpcResponseMessage {
RpcHeader Header = 1;
RpcResponseContainer Container = 2;
};
message TokenStuff {
string tkn = 1;
};
message InitSessionResponse {
bytes sesid = 1;
TokenStuff token = 2;
};
message MpGamerHandleDto {
string gh = 1;
};
message MpPeerAddressDto {
string addr = 1;
};
message InitPlayer2_Parameters {
MpGamerHandleDto gh = 1;
MpPeerAddressDto peerAddress = 2;
int32 discriminator = 3;
int32 seamlessType = 4;
uint32 connectionReason = 5;
};
message InitPlayerResult {
uint32 code = 1;
};
message Restriction {
int32 u1 = 1;
int32 u2 = 2;
int32 u3 = 3;
}
message GetRestrictionsData {
repeated Restriction restriction = 1;
repeated string unk2 = 2;
};
message GetRestrictionsResult {
GetRestrictionsData data = 1;
};
message PlayerIdSto {
int32 acctId = 1;
int32 platId = 2;
};
message MpSessionRequestIdDto {
PlayerIdSto requestor = 1;
int32 index = 2;
int32 hash = 3;
};
message QueueForSession_Seamless_Parameters {
MpSessionRequestIdDto requestId = 1;
uint32 optionFlags = 2;
int32 x = 3;
int32 y = 4;
};
message QueueForSessionResult {
uint32 code = 1;
};
message QueueEntered_Parameters {
uint32 queueGroup = 1;
MpSessionRequestIdDto requestId = 2;
uint32 optionFlags = 3;
};
message GuidDto {
fixed64 a = 1;
fixed64 b = 2;
};
message MpTransitionIdDto {
GuidDto value = 1;
};
message MpSessionIdDto {
GuidDto value = 1;
};
message SessionSubcommandEnterSession {
int32 index = 1;
int32 hindex = 2;
uint32 sessionFlags = 3;
uint32 mode = 4;
int32 size = 5;
int32 teamIndex = 6;
MpTransitionIdDto transitionId = 7;
uint32 sessionManagerType = 8;
int32 slotCount = 9;
};
message SessionSubcommandLeaveSession {
uint32 reason = 1;
};
message SessionSubcommandAddPlayer {
PlayerIdSto id = 1;
MpGamerHandleDto gh = 2;
MpPeerAddressDto addr = 3;
int32 index = 4;
};
message SessionSubcommandRemovePlayer {
PlayerIdSto id = 1;
};
message SessionSubcommandHostChanged {
int32 index = 1;
};
message SessionCommand {
uint32 cmd = 1;
string cmdname = 2;
SessionSubcommandEnterSession EnterSession = 3;
SessionSubcommandLeaveSession LeaveSession = 4;
SessionSubcommandAddPlayer AddPlayer = 5;
SessionSubcommandRemovePlayer RemovePlayer = 6;
SessionSubcommandHostChanged HostChanged = 7;
};
message scmds_Parameters {
MpSessionIdDto sid = 1;
int32 ncmds = 2;
repeated SessionCommand cmds = 3;
};

View File

@ -0,0 +1,276 @@
const protobuf = require("@citizenfx/protobufjs");
const playerDatas = {};
let slotsUsed = 0;
function assignSlotId() {
for (let i = 0; i < 32; i++) {
if (!(slotsUsed & (1 << i))) {
slotsUsed |= (1 << i);
return i;
}
}
return -1;
}
let hostIndex = -1;
protobuf.load(GetResourcePath(GetCurrentResourceName()) + "/rline.proto", function(err, root) {
if (err) {
console.log(err);
return;
}
const RpcMessage = root.lookupType("rline.RpcMessage");
const RpcResponseMessage = root.lookupType("rline.RpcResponseMessage");
const InitSessionResponse = root.lookupType("rline.InitSessionResponse");
const InitPlayer2_Parameters = root.lookupType("rline.InitPlayer2_Parameters");
const InitPlayerResult = root.lookupType("rline.InitPlayerResult");
const GetRestrictionsResult = root.lookupType("rline.GetRestrictionsResult");
const QueueForSession_Seamless_Parameters = root.lookupType("rline.QueueForSession_Seamless_Parameters");
const QueueForSessionResult = root.lookupType("rline.QueueForSessionResult");
const QueueEntered_Parameters = root.lookupType("rline.QueueEntered_Parameters");
const scmds_Parameters = root.lookupType("rline.scmds_Parameters");
function toArrayBuffer(buf) {
var ab = new ArrayBuffer(buf.length);
var view = new Uint8Array(ab);
for (var i = 0; i < buf.length; ++i) {
view[i] = buf[i];
}
return ab;
}
function emitMsg(target, data) {
emitNet('__cfx_internal:pbRlScSession', target, toArrayBuffer(data));
}
function emitSessionCmds(target, cmd, cmdname, msg) {
const stuff = {};
stuff[cmdname] = msg;
emitMsg(target, RpcMessage.encode({
Header: {
MethodName: 'scmds'
},
Content: scmds_Parameters.encode({
sid: {
value: {
a: 2,
b: 2
}
},
ncmds: 1,
cmds: [
{
cmd,
cmdname,
...stuff
}
]
}).finish()
}).finish());
}
function emitAddPlayer(target, msg) {
emitSessionCmds(target, 2, 'AddPlayer', msg);
}
function emitRemovePlayer(target, msg) {
emitSessionCmds(target, 3, 'RemovePlayer', msg);
}
function emitHostChanged(target, msg) {
emitSessionCmds(target, 5, 'HostChanged', msg);
}
onNet('playerDropped', () => {
try {
const oData = playerDatas[source];
delete playerDatas[source];
if (oData && hostIndex === oData.slot) {
const pda = Object.entries(playerDatas);
if (pda.length > 0) {
hostIndex = pda[0][1].slot | 0; // TODO: actually use <=31 slot index *and* check for id
for (const [ id, data ] of Object.entries(playerDatas)) {
emitHostChanged(id, {
index: hostIndex
});
}
} else {
hostIndex = -1;
}
}
if (!oData) {
return;
}
if (oData.slot > -1) {
slotsUsed &= ~(1 << oData.slot);
}
for (const [ id, data ] of Object.entries(playerDatas)) {
emitRemovePlayer(id, {
id: oData.id
});
}
} catch (e) {
console.log(e);
console.log(e.stack);
}
});
function makeResponse(type, data) {
return {
Header: {
},
Container: {
Content: type.encode(data).finish()
}
};
}
const handlers = {
async InitSession(source, data) {
return makeResponse(InitSessionResponse, {
sesid: Buffer.alloc(16),
/*token: {
tkn: 'ACSTOKEN token="meow",signature="meow"'
}*/
});
},
async InitPlayer2(source, data) {
const req = InitPlayer2_Parameters.decode(data);
playerDatas[source] = {
gh: req.gh,
peerAddress: req.peerAddress,
discriminator: req.discriminator,
slot: -1
};
return makeResponse(InitPlayerResult, {
code: 0
});
},
async GetRestrictions(source, data) {
return makeResponse(GetRestrictionsResult, {
data: {
}
});
},
async ConfirmSessionEntered(source, data) {
return {};
},
async QueueForSession_Seamless(source, data) {
const req = QueueForSession_Seamless_Parameters.decode(data);
playerDatas[source].req = req.requestId;
playerDatas[source].id = req.requestId.requestor;
playerDatas[source].slot = assignSlotId();
setTimeout(() => {
emitMsg(source, RpcMessage.encode({
Header: {
MethodName: 'QueueEntered'
},
Content: QueueEntered_Parameters.encode({
queueGroup: 69,
requestId: req.requestId,
optionFlags: req.optionFlags
}).finish()
}).finish());
if (hostIndex === -1) {
hostIndex = playerDatas[source].slot | 0;
}
emitSessionCmds(source, 0, 'EnterSession', {
index: playerDatas[source].slot | 0,
hindex: hostIndex,
sessionFlags: 0,
mode: 0,
size: Object.entries(playerDatas).filter(a => a[1].id).length,
//size: 2,
//size: Object.entries(playerDatas).length,
teamIndex: 0,
transitionId: {
value: {
a: 0,//2,
b: 0
}
},
sessionManagerType: 0,
slotCount: 32
});
setTimeout(() => {
// tell player about everyone, and everyone about player
const meData = playerDatas[source];
const aboutMe = {
id: meData.id,
gh: meData.gh,
addr: meData.peerAddress,
index: playerDatas[source].slot | 0
};
for (const [ id, data ] of Object.entries(playerDatas)) {
if (id == source || !data.id) continue;
emitAddPlayer(source, {
id: data.id,
gh: data.gh,
addr: data.peerAddress,
index: data.slot | 0
});
emitAddPlayer(id, aboutMe);
}
}, 150);
}, 50);
return makeResponse(QueueForSessionResult, {
code: 1
});
},
};
async function handleMessage(source, method, data) {
if (handlers[method]) {
return await handlers[method](source, data);
}
return {};
}
onNet('__cfx_internal:pbRlScSession', async (data) => {
const s = source;
try {
const message = RpcMessage.decode(new Uint8Array(data));
const response = await handleMessage(s, message.Header.MethodName, message.Content);
if (!response || !response.Header) {
return;
}
response.Header.RequestId = message.Header.RequestId;
emitMsg(s, RpcResponseMessage.encode(response).finish());
} catch (e) {
console.log(e);
console.log(e.stack);
}
});
});