GTX Posted April 12, 2014 Share Posted April 12, 2014 How can I write a code with fileSetPos and NOT removing/overwriting further bytes? An example: I have meta.xml: <meta> <file src="gta_tree_palm2.txd" /> <file src="veg_palm02.dff" /> <file src="music.mp3"></file> <script src="client.lua" type="client"></script> <info gamemodes="race" type="map" name="arr" author="t" version="1.0.0"></info> <map src="arr.map" dimension="0"></map> <settings> <setting name="#skins" value='[ "cj" ]'></setting> <setting name="#maxplayers" value="[ 128 ]"></setting> <setting name="#gamespeed" value="[ 1 ]"></setting> <setting name="#ghostmode" value='[ "true" ]'></setting> <setting name="#time" value="5:20"></setting> <setting name="#vehicleweapons" value='[ "true" ]'></setting> <setting name="#minplayers" value="[ 0 ]"></setting> <setting name="#weather" value="[ 2 ]"></setting> <setting name="#gravity" value="[ 0.008000 ]"></setting> <setting name="#waveheight" value="[ 0 ]"></setting> <setting name="#respawntime" value="[ 5 ]"></setting> <setting name="#locked_time" value="[ true ]"></setting> <setting name="#duration" value="[ 1800 ]"></setting> <setting name="#respawn" value='[ "none" ]'></setting> </settings> </meta> And I want to put the code below after without removing and <script src="common_messages.lua"/> <script src="common_messages.lua" type="client"/> So, it must look like this: <meta> <script src="common_messages.lua"/> <script src="common_messages.lua" type="client"/> <file src="gta_tree_palm2.txd" /> <file src="veg_palm02.dff" /> <file src="music.mp3"></file> <script src="client.lua" type="client"></script> <info gamemodes="race" type="map" name="arr" author="t" version="1.0.0"></info> <map src="arr.map" dimension="0"></map> <settings> <setting name="#skins" value='[ "cj" ]'></setting> <setting name="#maxplayers" value="[ 128 ]"></setting> <setting name="#gamespeed" value="[ 1 ]"></setting> <setting name="#ghostmode" value='[ "true" ]'></setting> <setting name="#time" value="5:20"></setting> <setting name="#vehicleweapons" value='[ "true" ]'></setting> <setting name="#minplayers" value="[ 0 ]"></setting> <setting name="#weather" value="[ 2 ]"></setting> <setting name="#gravity" value="[ 0.008000 ]"></setting> <setting name="#waveheight" value="[ 0 ]"></setting> <setting name="#respawntime" value="[ 5 ]"></setting> <setting name="#locked_time" value="[ true ]"></setting> <setting name="#duration" value="[ 1800 ]"></setting> <setting name="#respawn" value='[ "none" ]'></setting> </settings> </meta> My recent code looks like this: local file = fileOpen(":"..getResourceName(v).."/".."meta.xml") if file then fileSetPos(file, 0) if fileWrite(file, "<meta>", " \n<script src=\"common_messages.lua\" type=\"client\"/>", " \n<script src=\"common_messages.lua\" type=\"server\"/>") then end fileClose(file) end But it overwrites code after tag. (And meta tag itself, but that doesn't matter as I put it in again.) Any idea? Thanks in advance. Link to comment
Moderators IIYAMA Posted April 12, 2014 Moderators Share Posted April 12, 2014 https://wiki.multitheftauto.com/wiki/FileGetSize and start writing after that. Link to comment
ixjf Posted April 12, 2014 Share Posted April 12, 2014 Or rather use the XML functions. Link to comment
GTX Posted April 12, 2014 Author Share Posted April 12, 2014 Or rather use the XML functions. If so, how? As far as I know, I can't decide where node will be (I want it at the start). Link to comment
Saml1er Posted April 12, 2014 Share Posted April 12, 2014 function LoadMyFile () local pxml = xmlLoadFile(":"..getResourceName(v).."/".."meta.xml") if pxml local Xnode = xmlNodeGetChildren(pxml) for _,v in ipairs(Xnode) do if xmlNodeGetName(v) == "script" and xmlNodeGetAttribute(v, "src") == "common_messages.lua" then Exist_check = true else Exist_check = nil end end if not Exist_check then -- make sure it doesn't exist local Snode = xmlCreateChild(pxml, "script") xmlNodeSetAttribute(Snode, "src", "common_messages.lua") xmlNodeSetAttribute(Snode, "type", "server") xmlSaveFile(pxml) end xmlUnloadFile(pxml) end LoadMyFile () -- Call the function Link to comment
Alexs Posted April 12, 2014 Share Posted April 12, 2014 Or rather use the XML functions. The file functions are faster than XML functions. Link to comment
ixjf Posted April 12, 2014 Share Posted April 12, 2014 I think that's a bit obvious. It has to parse the XML file, file functions are for raw editing. Performance vs. readability, elegance and relatively low complexity - the latter clearly wins. You will most certainly not notice the performance impact. Link to comment
50p Posted April 12, 2014 Share Posted April 12, 2014 In this example, you can read the whole file and store it in a variable. Then use my string function below to add whatever you want, where ever you want. After that write the new string back to the file. function string.insert( str, val, pos ) -- eg: string.insert( "Hello and welcome", " Boss", 6 ); will return "Hello Boss and welcome" pos = pos or #str; return str:sub(1, pos-1) .. tostring(val) .. str:sub( pos, #str ); end Link to comment
GTX Posted April 12, 2014 Author Share Posted April 12, 2014 Thanks 50p but I can't store a string into variable. That's because meta.xml has those " in it. I tried that but it didn't work: if file then fileSetPos(file, 0) local index = 0 while string.char(string.byte(fileRead(file, 1))) ~= ">" do index = index + 1 fileSetPos(file, index) end fileSetPos(file, index) local buffer = fileRead(file, fileGetSize(file)) if buffer then fileClose(file) fileDelete(":"..getResourceName(v).."/".."meta.xml") local newFile = fileCreate(":"..getResourceName(v).."/".."meta.xml") if fileWrite(newFile, "<meta>", "\n<script src=\"common_messages.lua\" type=\"client\"/>", "\n<script src=\"common_messages.lua\" type=\"server\"/>") then end fileSetPos(newFile, fileGetSize(newFile)) if fileWrite(newFile, buffer) then outputChatBox("Done") end end end Link to comment
GTX Posted April 12, 2014 Author Share Posted April 12, 2014 I apologize for double post. I made it working but now it got even worse. I don't know if this is a bug or what. When I fileWrite a meta and do /refreshall, it says: Couldn't parse meta for etc... All I know (for now) meta was converted to UNIX (I'm not sure what is it, but I think it is kind of EOL conversion...). Before it was Dos/Windows. (This 'conversions' can be seen in Notepad++). Wondering now, how to fix that? Link to comment
Bonsai Posted April 12, 2014 Share Posted April 12, 2014 Why is the position of those nodes important? Just wondering. Are you sure its because of some conversion? Have u tried to convert it back in Notepad and check if it works? Maybe there is just some syntax error. Link to comment
GTX Posted April 12, 2014 Author Share Posted April 12, 2014 Nah. I double-triple checked. Working meta is same as non-working meta. Position of those nodes is important because my common_messages.lua is having wrapper, which disables outputChatBox function. Link to comment
Bonsai Posted April 12, 2014 Share Posted April 12, 2014 If you use a custom resource loading system couldn't you just pretend its at the first position? Actually you wouldn't even have to add it to any map then. Just noticed that other topic about cancel outputChatBox was made by you Link to comment
ixjf Posted April 13, 2014 Share Posted April 13, 2014 You could rather block all resources from calling outputChatBox except the ones you want, through ACL. I suppose the default group for all resources and users is "Default" - block access to the function: <right name="function.outputChatBox" access="false"/> .. and then add the resources you want to have access to the function to another group that allows access to it. Link to comment
GTX Posted April 13, 2014 Author Share Posted April 13, 2014 Alright, I made it working. All I had to do is put \r\n to define new lines. (I think MTA hates Unix EOL conversions at meta). Thank you all for your time. Link to comment
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now