Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit591c81e

Browse files
committed
feat: record printer
1 parent87cc631 commit591c81e

File tree

10 files changed

+370
-115
lines changed

10 files changed

+370
-115
lines changed

‎sonorancad/core/client_nui/index.html‎

Lines changed: 100 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,42 @@
11
<html>
22
<head>
33
<scriptsrc="nui://game/ui/jquery.js"type="text/javascript"></script>
4-
<scriptsrc="js/http.js"tyle="text/javascript"></script>
4+
<scriptsrc="js/http.js"type="text/javascript"></script>
5+
<style>
6+
html,
7+
body {
8+
margin:0;
9+
padding:0;
10+
background: transparent;
11+
overflow: hidden;
12+
}
13+
14+
#recordPrinterContainer {
15+
position: absolute;
16+
inset:0;
17+
z-index:10;
18+
}
19+
20+
#bodycamOverlayContainer {
21+
position: absolute;
22+
inset:0;
23+
display: none;
24+
pointer-events: none;
25+
z-index:999;
26+
}
27+
28+
#bodycamOverlayImage {
29+
position: absolute;
30+
display: none;
31+
height:6vh;
32+
}
33+
</style>
534
</head>
6-
<bodystyle="display: none">
35+
<body>
36+
<divid="recordPrinterContainer"></div>
37+
<divid="bodycamOverlayContainer">
38+
<imgsrc="./img/logo.gif"alt="header"id="bodycamOverlayImage"/>
39+
</div>
740
<script>
841
// CRED: https://stackoverflow.com/questions/6150289/how-can-i-convert-an-image-into-base64-string-using-javascript/20285053#20285053
942
functiontoDataUrl(url,callback){
@@ -39,8 +72,65 @@
3972
<scriptsrc="https://cdnjs.cloudflare.com/ajax/libs/howler/2.1.1/howler.min.js"type="text/javascript"></script>
4073
<script>
4174
varaudioPlayer=null;
42-
varshowGif=false;
75+
varbodycamOverlayVisible=false;
76+
constrecordPrinterContainer=document.getElementById("recordPrinterContainer");
77+
constoverlayContainer=document.getElementById("bodycamOverlayContainer");
78+
constoverlayImage=document.getElementById("bodycamOverlayImage");
79+
constrecordPrinterFrame=document.createElement("iframe");
80+
recordPrinterFrame.src=`https://cfx-nui-${GetParentResourceName()}/submodules/recordPrinter/html/ui.html`;
81+
recordPrinterFrame.style.position="absolute";
82+
recordPrinterFrame.style.top="0px";
83+
recordPrinterFrame.style.left="0px";
84+
recordPrinterFrame.style.right="0px";
85+
recordPrinterFrame.style.bottom="0px";
86+
recordPrinterFrame.style.width="100%";
87+
recordPrinterFrame.style.height="100%";
88+
recordPrinterFrame.style.border="0px";
89+
recordPrinterFrame.style.zIndex="10";
90+
recordPrinterContainer.appendChild(recordPrinterFrame);
91+
functionpositionOverlay(location){
92+
overlayImage.style.top="";
93+
overlayImage.style.right="";
94+
overlayImage.style.bottom="";
95+
overlayImage.style.left="";
96+
97+
switch(location){
98+
case"top-left":
99+
overlayImage.style.top="0";
100+
overlayImage.style.left="0";
101+
break;
102+
case"top-right":
103+
overlayImage.style.top="0";
104+
overlayImage.style.right="0";
105+
break;
106+
case"bottom-left":
107+
overlayImage.style.bottom="0";
108+
overlayImage.style.left="0";
109+
break;
110+
case"bottom-right":
111+
overlayImage.style.bottom="0";
112+
overlayImage.style.right="0";
113+
break;
114+
}
115+
}
116+
117+
functionsetOverlayVisibility(visible,location){
118+
bodycamOverlayVisible=!!visible;
119+
if(bodycamOverlayVisible){
120+
overlayContainer.style.display="block";
121+
overlayImage.style.display="block";
122+
positionOverlay(location||"top-left");
123+
}else{
124+
overlayImage.style.display="none";
125+
overlayContainer.style.display="none";
126+
}
127+
}
128+
43129
window.addEventListener("message",function(event){
130+
if(event.data.recordPrinter){
131+
console.log("Forwarding message to recordPrinterFrame:",event.data);
132+
recordPrinterFrame.contentWindow.postMessage(event.data,"*");
133+
}
44134
if(event.data.type=="playSound"){
45135
if(audioPlayer!=null){
46136
audioPlayer.pause();
@@ -51,34 +141,15 @@
51141
audioPlayer.volume(event.data.transactionVolume);
52142
audioPlayer.play();
53143
}
54-
if(event.data.type=="toggleGif"){
55-
showGif=!showGif;
56-
if(showGif){
57-
document.body.style.display="block";
58-
switch(event.data.location){
59-
case"top-left":
60-
document.getElementById("overlay").style.top="0";
61-
document.getElementById("overlay").style.left="0";
62-
break;
63-
case"top-right":
64-
document.getElementById("overlay").style.top="0";
65-
document.getElementById("overlay").style.right="0";
66-
break;
67-
case"bottom-left":
68-
document.getElementById("overlay").style.bottom="0";
69-
document.getElementById("overlay").style.left="0";
70-
break;
71-
case"bottom-right":
72-
document.getElementById("overlay").style.bottom="0";
73-
document.getElementById("overlay").style.right="0";
74-
break;
75-
}
76-
}else{
77-
document.body.style.display="none";
78-
}
144+
if(event.data.type==="bodycamOverlay"){
145+
setOverlayVisibility(event.data.visible,event.data.location);
146+
}elseif(event.data.type==="toggleGif"){
147+
// Backwards compatibility: flip current visibility
148+
constnextVisibility=!bodycamOverlayVisible;
149+
constlocation=nextVisibility ?event.data.location :null;
150+
setOverlayVisibility(nextVisibility,location);
79151
}
80152
});
81153
</script>
82-
<imgsrc="./img/logo.gif"alt="header"style="height: 6vh; position: absolute"id="overlay"/>
83154
</body>
84155
</html>

‎sonorancad/core/pdf.js‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
constpath=require("path");
21
exports("SaveBase64ToFile",function(base64String,filename){
32
letbase64Image=base64String.split(";base64,").pop();
43
fs.writeFile(filename,base64Image,{encoding:"base64"},function(err){

‎sonorancad/fxmanifest.lua‎

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@ games {'gta5'}
33

44
author'Sonoran CAD'
55
description'Sonoran CAD FiveM Integration'
6-
version'3.2.14'
6+
version'3.2.17'
77

88
server_scripts {
99
'core/http.js'
1010
,'core/unzipper/unzip.js'
1111
,'core/image.js'
12+
,'core/pdf.js'
1213
,'core/logging.lua'
1314
,'core/shared_functions.lua'
1415
,'core/configuration.lua'
@@ -23,7 +24,7 @@ server_scripts {
2324
,'submodules/**/sv_*.lua'
2425
,'submodules/**/sv_*.js'
2526
,'core/screenshot.lua'
26-
}
27+
}
2728
client_scripts {
2829
'core/logging.lua'
2930
,'core/headshots.lua'
@@ -44,7 +45,11 @@ files {
4445
'core/client_nui/sounds/*.mp3',
4546
'core/client_nui/img/logo.gif',
4647
'submodules/**/*.mp3',
47-
'submodules/postals/*.json'
48+
'submodules/postals/*.json',
49+
'submodules/recordPrinter/html/main.js',
50+
'submodules/recordPrinter/html/style.css',
51+
'submodules/recordPrinter/html/ui.html',
52+
'submodules/recordPrinter/pdfs/**/*.pdf',
4853
}
4954

5055
data_file'DLC_ITYP_REQUEST''stream/**/*.ytyp'

‎sonorancad/submodules/bodycam/cl_bodycam.lua‎

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,8 @@ CreateThread(function()
165165
bodyCamOn=false
166166
ifshowOverlaythen
167167
SendNUIMessage({
168-
type='toggleGif',
168+
type='bodycamOverlay',
169+
visible=false,
169170
location=pluginConfig.overlayLocation
170171
})
171172
end
@@ -177,7 +178,8 @@ CreateThread(function()
177178
bodyCamOn=true
178179
ifshowOverlaythen
179180
SendNUIMessage({
180-
type='toggleGif',
181+
type='bodycamOverlay',
182+
visible=true,
181183
location=pluginConfig.overlayLocation
182184
})
183185
end
@@ -245,7 +247,8 @@ CreateThread(function()
245247
end
246248
ifbodyCamOnthen
247249
SendNUIMessage({
248-
type='toggleGif',
250+
type='bodycamOverlay',
251+
visible=showOverlay,
249252
location=pluginConfig.overlayLocation
250253
})
251254
end

‎sonorancad/submodules/recordPrinter/cl_recordPrinter.lua‎

Lines changed: 71 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,49 @@
77
]]
88
CreateThread(function()Config.LoadPlugin("recordPrinter",function(pluginConfig)
99
localprintQueue= {}
10+
localfunctionprettyFileName(path,opts)
11+
opts=optsor {}
12+
localmax_len=opts.max_len==niland40oropts.max_len
13+
localkeep_ext=opts.keep_extorfalse
14+
localdash_style=opts.dash_styleor"spaced-dash"-- choices: space | spaced-dash | keep
15+
16+
-- 1) take just the last path segment
17+
localbase=path:match("([^/\\]+)$")orpath
18+
19+
-- 2) optionally drop extension
20+
localext=base:match("%.[%w]+$")or""
21+
localname=keep_extandbaseorbase:gsub("%.[%w]+$","")
22+
23+
-- 3) strip leading UUID (8-4-4-4-12) + common separators
24+
localuuidPattern="^(%x%x%x%x%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%-%x%x%x%x%x%x%x%x%x%x%x%x)[%s%-%_]*"
25+
name=name:gsub(uuidPattern,"")
26+
27+
-- 4) normalize separators
28+
name=name:gsub("[_]+","")-- underscores -> spaces
29+
ifdash_style=="space"then
30+
name=name:gsub("%s*%-%s*","")
31+
elseifdash_style=="spaced-dash"then
32+
name=name:gsub("%s*%-%s*"," -")
33+
else
34+
-- "keep": leave dashes as-is
35+
end
36+
37+
-- 5) trim & collapse whitespace
38+
name=name:gsub("%s+",""):gsub("^%s+",""):gsub("%s+$","")
39+
40+
-- 6) clip if too long
41+
ifmax_lenand#name>max_lenthen
42+
name=name:sub(1,max_len-1)..""
43+
end
44+
45+
ifkeep_extandext~=""then
46+
name=name..ext
47+
end
48+
49+
-- fallback
50+
ifname==""thenname="(untitled)"end
51+
returnname
52+
end
1053
RegisterNetEvent('SonoranCAD::recordPrinter:PrintQueue',function(data)
1154
table.insert(printQueue,data)
1255
-- Check queue size
@@ -24,11 +67,21 @@ CreateThread(function() Config.LoadPlugin("recordPrinter", function(pluginConfig
2467
})
2568
end)
2669
RegisterCommand(pluginConfig.printQueueCommand,function()
70+
if#printQueue==0then
71+
sendChat({255,200,0},"Your print queue is empty.")
72+
return
73+
end
74+
2775
fori,urlinipairs(printQueue)do
76+
localrawPath=url
77+
iftype(rawPath)~='string'then
78+
rawPath=tostring(rawPathor'')
79+
end
80+
localdisplayName=prettyFileName(rawPath, {keep_ext=true,max_len=pluginConfig.queueDisplayMaxLengthor48 })
2881
TriggerEvent('chat:addMessage', {
2982
color= {0,255,0},
3083
multiline=true,
31-
args= {"Record Printer","Record"..i..":"..url}
84+
args= {"Record Printer","Record"..i..":"..displayName}
3285
})
3386
end
3487
end,false)
@@ -109,7 +162,7 @@ CreateThread(function() Config.LoadPlugin("recordPrinter", function(pluginConfig
109162
returnisInVehicleWithPrinter(4.0)orisNearPrinterObject(3.5)orisAtPrinterCoord(3.5)
110163
end
111164

112-
localfunctionsendChat(color,msg)
165+
functionsendChat(color,msg)
113166
TriggerEvent('chat:addMessage', {
114167
color=coloror {255,255,255},
115168
multiline=true,
@@ -156,8 +209,15 @@ CreateThread(function() Config.LoadPlugin("recordPrinter", function(pluginConfig
156209

157210
-- For now, just notify and remove it from the queue after "printing"
158211
sendChat({0,255,0}, ("Printing: queue #%d"):format(idx))
212+
SendNuiMessage(json.encode({action='openUI',link=url,first=true,type='pdf',recordPrinter=true }))
213+
SetNuiFocus(true,true)
159214
table.remove(printQueue,idx)
160215
end,false)
216+
TriggerEvent('chat:addSuggestion','/'..pluginConfig.printCommand,'Print a record from your print queue.', {
217+
{name='index',help='The position in your print queue to print (see /'..pluginConfig.printQueueCommand..')'}
218+
})
219+
TriggerEvent('chat:addSuggestion','/'..pluginConfig.printQueueCommand,'View your current print queue.')
220+
TriggerEvent('chat:addSuggestion','/'..pluginConfig.clearPrintQueueCommand,'Clear your current print queue.')
161221
-- State
162222
localholdingDoc=false
163223
localdoc_link=nil
@@ -287,11 +347,10 @@ CreateThread(function() Config.LoadPlugin("recordPrinter", function(pluginConfig
287347
DeleteEntity(e.entityObject)
288348
end
289349
TriggerServerEvent('SonoranPDF:destroyWorldPDF',closestId)
290-
SendNuiMessage(json.encode({action='openui',link=e.pdf_link,first=false,type='pdf'}))
350+
SendNuiMessage(json.encode({action='openUI',link=e.pdf_link,first=false,type='pdf',recordPrinter=true }))
291351
ToggleDocHold(true)
292352
SetNuiFocusKeepInput(true)
293353
table.remove(WorldDocs,closestId)
294-
DisplayNotification(pluginConfig.translations.putPhotoAway)
295354
end
296355

297356
-- G: destroy in world
@@ -315,30 +374,27 @@ CreateThread(function() Config.LoadPlugin("recordPrinter", function(pluginConfig
315374
-- QB: item.info.pdf_link
316375
locallink= (itemanditem.infoanditem.info.pdf_link)ornil
317376
ifnotlinkorlink==''thenreturnend
318-
SendNuiMessage(json.encode({action='openui',link=link,first=false,type='pdf'}))
377+
SendNuiMessage(json.encode({action='openUI',link=link,first=false,type='pdf',recordPrinter=true }))
319378
ToggleDocHold(true)
320-
SetNuiFocusKeepInput(true)
321-
DisplayNotification(pluginConfig.translations.putPhotoAway)
379+
SetNuiFocus(true,true)
322380
end)
323381

324382
RegisterNetEvent('sonoran:lookpdf:esx',function(item)
325383
-- ESX (ox): entry.metadata.pdf_link
326384
locallink= (itemanditem.metadataanditem.metadata.pdf_link)ornil
327385
ifnotlinkorlink==''thenreturnend
328-
SendNuiMessage(json.encode({action='openui',link=link,first=false,type='pdf'}))
386+
SendNuiMessage(json.encode({action='openUI',link=link,first=false,type='pdf',recordPrinter=true }))
329387
ToggleDocHold(true)
330-
SetNuiFocusKeepInput(true)
331-
DisplayNotification(pluginConfig.translations.putPhotoAway)
388+
SetNuiFocus(true,true)
332389
end)
333390

334391
-- Optional: direct open (e.g., when a brand-new PDF is produced and you want it to be “First” so putting away adds to inventory)
335392
RegisterNetEvent('SonoranPDF:Open',function(url)
336393
ifnoturlorurl==''thenreturnend
337394
doc_link=url
338-
SendNuiMessage(json.encode({action='openui',link=url,first=true,type='pdf'}))-- first=true -> inventory put-away
395+
SendNuiMessage(json.encode({action='openUI',link=url,first=true,type='pdf',recordPrinter=true }))-- first=true -> inventory put-away
339396
ToggleDocHold(true)
340-
SetNuiFocusKeepInput(true)
341-
DisplayNotification(pluginConfig.translations.pressToDrop)
397+
SetNuiFocus(true,true)
342398
end)
343399

344400
-- =========================
@@ -422,7 +478,7 @@ CreateThread(function() Config.LoadPlugin("recordPrinter", function(pluginConfig
422478
ifholdingDocthen
423479
DisableControlAction(0,202,true)-- BACK
424480
ifIsDisabledControlJustPressed(0,202)then
425-
SendNuiMessage(json.encode({action='closeui'}))
481+
SendNuiMessage(json.encode({action='closeui',recordPrinter=true }))
426482
DisableControlAction(0,202,false)
427483
SetNuiFocus(false,false)
428484
end
@@ -464,4 +520,4 @@ CreateThread(function() Config.LoadPlugin("recordPrinter", function(pluginConfig
464520
map_net=nil
465521
end
466522
end
467-
end)end)
523+
end)end)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp