1
0
mirror of https://github.com/citizenfx/cfx-server-data.git synced 2025-01-06 21:02: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 } }
map 'map.lua'
fx_version 'adamant'
game 'gta5'

View File

@ -1,3 +1,6 @@
resource_type 'map' { gameTypes = { ['basic-gamemode'] = true } }
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

@ -7,4 +7,7 @@ chat_theme 'gtao' {
msgTemplates = {
default = '<b>{0}</b><span>{1}</span>'
}
}
}
game 'common'
fx_version 'adamant'

View File

@ -3,10 +3,10 @@
}
.chat-window {
--size: calc((((2.7vw / 1.77777) * 1.2)) * 6);
--size: calc(((2.7vh * 1.2)) * 6);
position: absolute;
right: calc(1.56vw);
right: calc(2.77vh);
top: calc(50% - (var(--size) / 2));
height: var(--size) !important;
@ -33,10 +33,10 @@
font-family: Font2, sans-serif;
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);
line-height: calc((2.7vw / 1.77777) * 1.2);
line-height: calc(2.7vh * 1.2);
margin-bottom: 0;
}
@ -55,7 +55,7 @@
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 {
@ -69,8 +69,8 @@
.chat-input {
position: absolute;
right: calc(1.56vw);
bottom: calc(1.56vw);
right: calc(2.77vh);
bottom: calc(2.77vh);
background: inherit !important;
@ -86,7 +86,7 @@
.chat-input > div {
background-color: rgba(0, 0, 0, .6);
padding: calc(0.15625vw / 2);
padding: calc(0.28vh / 2);
}
.chat-input .prefix {
@ -97,20 +97,32 @@
.chat-input > div + div {
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%;
text-align: left;
}
.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;
}
textarea {
background: transparent;
border: calc(0.15625vw / 2) solid rgba(180, 180, 180, .6);
padding: calc(0.15625vw / 2);
padding-left: calc(3.5% + (0.15625vw / 2));
}
border: calc(0.28vh / 2) solid rgba(180, 180, 180, .6);
padding: calc(0.28vh / 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 chatInputActivating = false
local chatHidden = true
@ -194,7 +196,7 @@ Citizen.CreateThread(function()
Wait(0)
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
chatInputActivating = true
@ -205,7 +207,7 @@ Citizen.CreateThread(function()
end
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)
chatInputActivating = false

View File

@ -1,26 +1,30 @@
description 'chat management stuff'
ui_page 'html/index.html'
client_script 'cl_chat.lua'
server_script 'sv_chat.lua'
files {
'html/index.html',
'html/index.css',
'html/config.default.js',
'html/config.js',
'html/App.js',
'html/Message.js',
'html/Suggestions.js',
'html/vendor/vue.2.3.3.min.js',
'html/vendor/flexboxgrid.6.3.1.min.css',
'html/vendor/animate.3.5.2.min.css',
'html/vendor/latofonts.css',
'html/vendor/fonts/LatoRegular.woff2',
'html/vendor/fonts/LatoRegular2.woff2',
'html/vendor/fonts/LatoLight2.woff2',
'html/vendor/fonts/LatoLight.woff2',
'html/vendor/fonts/LatoBold.woff2',
'html/vendor/fonts/LatoBold2.woff2',
}
description 'chat management stuff'
ui_page 'html/index.html'
client_script 'cl_chat.lua'
server_script 'sv_chat.lua'
files {
'html/index.html',
'html/index.css',
'html/config.default.js',
'html/config.js',
'html/App.js',
'html/Message.js',
'html/Suggestions.js',
'html/vendor/vue.2.3.3.min.js',
'html/vendor/flexboxgrid.6.3.1.min.css',
'html/vendor/animate.3.5.2.min.css',
'html/vendor/latofonts.css',
'html/vendor/fonts/LatoRegular.woff2',
'html/vendor/fonts/LatoRegular2.woff2',
'html/vendor/fonts/LatoLight2.woff2',
'html/vendor/fonts/LatoLight.woff2',
'html/vendor/fonts/LatoBold.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
resource_manifest_version '05cfa83c-a124-4cfa-a768-c24a5811d8f9'
fx_version 'adamant'
game 'gta5'

View File

@ -8,7 +8,8 @@ server_scripts {
"mapmanager_server.lua"
}
resource_manifest_version "77731fab-63ca-442c-a67b-abc70f28dfa5"
fx_version 'adamant'
games { 'gta5', 'rdr3' }
server_export "getCurrentGameType"
server_export "getCurrentMap"
@ -16,4 +17,6 @@ server_export "changeGameType"
server_export "changeMap"
server_export "doesMapSupportGameType"
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)
AddEventHandler('getMapDirectives', function(add)
if not CreateScriptVehicleGenerator then
return
end
add('vehicle_generator', function(state, name)
return function(opts)
local x, y, z, heading

View File

@ -8,3 +8,8 @@ export 'loadSpawns'
export 'setAutoSpawn'
export 'setAutoSpawnCallback'
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
function loadScene(x, y, z)
if not NewLoadSceneStart then
return
end
NewLoadSceneStart(x, y, z, 0.0, 0.0, 0.0, 20.0, 0)
while IsNewLoadSceneActive() do
@ -258,14 +262,18 @@ function spawnPlayer(spawnIdx, cb)
-- release the player model
SetModelAsNoLongerNeeded(spawn.model)
-- RDR3 player model bits
if N_0x283978a15512b2fe then
N_0x283978a15512b2fe(PlayerPedId(), true)
end
end
-- preload collisions for the spawnpoint
RequestCollisionAtCoord(spawn.x, spawn.y, spawn.z)
-- spawn the player
--ResurrectNetworkPlayer(GetPlayerId(), spawn.x, spawn.y, spawn.z, spawn.heading)
local ped = GetPlayerPed(-1)
local ped = PlayerPedId()
-- V requires setting coords as well
SetEntityCoordsNoOffset(ped, spawn.x, spawn.y, spawn.z, false, false, false, true)
@ -328,7 +336,7 @@ Citizen.CreateThread(function()
while true do
Citizen.Wait(50)
local playerPed = GetPlayerPed(-1)
local playerPed = PlayerPedId()
if playerPed and playerPed ~= -1 then
-- 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;
const process = child_process.fork(
require.resolve('./yarn_cli.js'),
['install'],
['install', '--ignore-scripts'],
{
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

@ -15,4 +15,7 @@ files {
'html/res/futurastd-medium.woff',
'html/res/futurastd-medium.ttf',
'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 not listOn then
local players = {}
ptable = GetPlayers()
local ptable = GetActivePlayers()
for _, i in ipairs(ptable) do
local wantedLevel = GetPlayerWantedLevel(i)
r, g, b = GetPlayerRgbColour(i)
@ -35,18 +35,6 @@ Citizen.CreateThread(function()
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)
local replacements = {
['&' ] = '&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);
}
});
});