|
Post by X-Drop on Jan 12, 2006 11:48:39 GMT -5
[EDIT Jan. 13th, 2006]Here is a temp fix for anyone needing a file path function, function Lunar_path() local i, j =string.find(debug.getinfo(Lunar_path).source, "Lunar\\scripts\\") return string.sub(debug.getinfo(Lunar_path).source, 2, j) endor function Lunar_path() local filePath=string.gsub(debug.getinfo(1).source, "@", "", 1) return string.sub(filePath,1,string.len(filePath)-string.len(Windower.script_GetArg(1))) endJust add this function to your script. An example of its usage, Path = Lunar_path() [Original thread]Ok this has been driving me nuts. I have been messing around with Lua io functions alot lately (io.open, io.read, io.write, etc...). Now the part that is stumping me is find the file path to the file I wanna open. I've have googled my ass off trying to find some kind of function or constant that I could call and retrieve the file path of anything. I would settle for a function/constant that returned the current file path. But my patients is growing thin and I'm nearly ready to just specify the file path in full. Look at Nebula's attempt to parser the Windower.ini file with ExpMon, -- Try reading windower.ini for the Y Res resY = 600 --value incase unable to load from ini and not in the cmdline function loadcfg () local cfg = assert(io.open("../../../"..INIFile,"r")) for line in cfg:lines() do if string.find(line,"Y Resolution") then resY = tonumber(string.sub(line,string.find(line,"%d+"))) break end end end pcall(loadcfg) --don't hang on not being able to open the configI was ready to use this very approach too, but this never does manage to open up the ini file. Instead, local cfg = assert(io.open("../../../"..INIFile,"r"))returns a Lua error as you cannot concatinate the constant INIFILE. This error never gets displayed because the function is called in safe mode, pcall. When I saw this, I thought I could lose the concat and see what the value of the constant INIFILE was. But sadly it is nil. Nebula... SDphantom.... anyone know any constants or functions that can be used to return a file's path??
|
|
sdphantom
Full Member
Savior and Destroyer
Posts: 230
|
Post by sdphantom on Jan 12, 2006 13:33:18 GMT -5
I was messing around with my own version of ExpWatch that saves its config data to a binary file. In my debugging of the script, I found that the file was being written into the FFXI program directory instead of the directory that the script was in. Probably something to fix whenever Tiny has the time to.
|
|
|
Post by TinyTerror on Jan 13, 2006 14:59:40 GMT -5
This is something that I can actually help you with right away. A while back someone brought up this problem and I added pol and windower path functions to Lunar. Being completely scatter brained, I never added anything to the docs. So yeah, the functions are Windower.windower_GetPath() and Windower.windower_GetPolPath(). Both return strings containing the path to the windower directory and the playonline directory respectfully. They should already be in the latest public release.
Maybe one of you guys could help me update the docs in an easier to use format or something. Anyway, hope that helped.
|
|
|
Post by X-Drop on Jan 13, 2006 15:31:02 GMT -5
Awsome, man! This is exactly what I needed!! ;D
|
|
|
Post by X-Drop on Jan 13, 2006 17:17:41 GMT -5
there went that honeymoon..... The two file path functions are only returning the drive, "C", instead of the complete path. I was gonna do a quick fix for ppl who cannot get Lunar to display images, but these functions don't work for me. Let me just add that I currently have no problem displaying images-- they load just fine for me.
Run this script and see if you get the same incomplete file path. Display=Graphics.text_CreateObject() Graphics.text_SetColor(255,255,255,255,Display) Graphics.text_SetPosition(50,400,Display) Graphics.text_SetFont("Arial",12,Display)
filepath = Windower.windower_GetPath() .. "/Windower.ini"
Output = string.format("Output of Windower.windower_GetPath() : \"%s\"\r\nOutput of Windower.windower_GetPolPath() : \"%s\"\r\nAttempted file path to Windower.ini file : \"%s\"\r\n", Windower.windower_GetPath(), Windower.windower_GetPolPath(), filepath)
Graphics.text_SetText(Output, Display)
Windower.script_Sleep(15000)
|
|
|
Post by TinyTerror on Jan 13, 2006 18:15:23 GMT -5
Checking the code real quick.
|
|
|
Post by TinyTerror on Jan 13, 2006 18:28:34 GMT -5
Problem confirmed. This would probably be why I didn't include these functions in the docs >_<
I think its probably an issue with the conversion between unicode and character strings that goes on in the path functions thats messing this up. Sorry this didn't work out for you. I'll see if I can come up with anything.
|
|
|
Post by TinyTerror on Jan 13, 2006 19:03:34 GMT -5
Ok, I found a realy wierd way to do this, but it works. Using the debug library, you can get info on any function loaded by your script. Including the file it was loaded from With a little bit of creative sub string voodoo, you can pull out the path of your currently running script. Here's the code: function anyfunction() Windower.console_Write("Blah!") end
MyInfo=debug.getinfo(anyfunction) MyPath=MyInfo.source
Output=string.format("Path: %s",MyPath) Windower.console_Write(Output)
The output is the path of the script where anyfunction is preceded by an @. I know its not the cleanest solution, but it works. If your INI file is in the same directory as the script, its just a matter of stripping the @, grabbing everything up to and including the last \ and appending your filename onto the end. Now thats what I call dropping some science
|
|
|
Post by X-Drop on Jan 13, 2006 19:19:27 GMT -5
sub string voodoo?? ..... I'll take it!!^^ Way to think outside the box. I have not looked at Lua's debug library yet, so I'm gonna go check this out. Thx man. [EDIT]Wow.... your fix worked like a charm! This is how I formed the function for my script, function get_path() return string.gsub(debug.getinfo(get_path).source, "@", "", 1) endGonna post a thread to help ppl with image problems now.
|
|
|
Post by TinyTerror on Jan 13, 2006 19:58:23 GMT -5
Yeah, that might work to fix the image problem. Let me know what you come up with. This is why Lua was a good choice. You can use it to correct the shittyness of the rest of lunar ^_^
|
|
sdphantom
Full Member
Savior and Destroyer
Posts: 230
|
Post by sdphantom on Jan 13, 2006 20:00:28 GMT -5
Cool, now I can get these codes working right, lol.
Oh, reguarding to writing binary code to a file, Lua supportd embedded zeros in strings, making them binary arrays rather than conventional strings, but the file:write() function doesn't support these and cut off at the first zero it comes up to.
Aparently, Lua uses the C function, fputs() to write to files. Just a heads up in case anyone else is attempting this.
I wrote a couple Lua functions that convert numbers passed into binary strings that file:write() should support. Basically, converting the number into base 255 and adding 1 to each byte to avoid embedding a zero in the string. the second function takes this string and converts it back into a number.
function binenc(dat,reqlen) local ret if not reqlen then reqlen=0 end if reqlen>0 and dat>(255^reqlen) then dat=(255^reqlen) end ret="" while dat>0 do ret=string.char(math.mod(dat,255)+1)..ret dat=math.floor(dat/255) end if string.len(ret)<reqlen then ret=string.rep("\001",reqlen-string.len(ret))..ret end return ret end
function bindec(dat) local ret if string.len(dat)<=0 then return 0 end ret=0 for i=1,string.len(dat) do ret=ret+((255^(i-1))*(string.byte(dat,(string.len(dat)+1-i))-1)) end return ret end
Use:
-- intVal = the number to be converted -- reqLen (optional) = arguement that sets how long to make the string binString=binenc(intVal,reqLen)
-- binString = binary string encoded by the binenc() function intVal=bindec(binString)
|
|
sdphantom
Full Member
Savior and Destroyer
Posts: 230
|
Post by sdphantom on Jan 13, 2006 20:53:16 GMT -5
Lol, and another thing, to get the filename of your script, use
Windower.script_GetArg(1)
Probably edit the function to get the directory the script is in by using this modification
function get_path() local filePath=string.gsub(debug.getinfo(1).source, "@", "", 1) return string.sub(filePath,1,string.len(filePath)-string.len(Windower.script_GetArg(1))) end
<edit: read more on the debug.getinfo() and found when given a number, it points to the function at that call stack position, 0 is debug.getinfo() itself, 1 is the function that called it, etc. Changed the code to reflect this and be capable of having the function name changed without needing to change the value.>
|
|
sdphantom
Full Member
Savior and Destroyer
Posts: 230
|
Post by sdphantom on Jan 13, 2006 21:07:12 GMT -5
This is why Lua was a good choice. You can use it to correct the shittyness of the rest of lunar ^_^ No real comment, but reading that just makes me (/laugh ). Lol, ^.^; b It's nice having a pre-coded interpreter that works so well. Just the task of coding a loader and addons.
|
|
|
Post by X-Drop on Jan 13, 2006 21:51:52 GMT -5
I forgot all about Windower.script_GetArg(1)... lol I copy/pasted this to the top of the thread. function get_path() local filePath=string.gsub(debug.getinfo(1).source, "@", "", 1) return string.sub(filePath,1,string.len(filePath)-string.len(Windower.script_GetArg(1))) endWithout Windower.script_GetArg(1), I was getting my path like this, function Lunar_path() local i, j =string.find(debug.getinfo(Lunar_path).source, "Lunar\\scripts\\") return string.sub(debug.getinfo(Lunar_path).source, 2, j) end
...lol.... brick wall!! Using debug.getinfo I now know that Windower.primitive_SetTexture(arg1,arg2) is a C function. And that being said, fixing the image path issue is beyond my capabilities. (/laugh )
|
|
|
Post by TinyTerror on Jan 13, 2006 23:35:54 GMT -5
Yeah, I dont think it would work for images after having checked the source again.
Oh, by the way, if anyone is interested in what the primitive set texture code looks like, here it is:
int GraphicsLib::PrimitiveSetTextureFromFile(lua_State *L) { SDL_SemWait(GetSemaphore()); if(GetWindower(L)!=NULL) { if(lua_gettop(L)!=2) { lua_pushboolean(L,false); luaL_error(L,"Wrong number of arguments to call primitive_SetTexture."); } else { char* File=(char*)lua_tostring(L,1); int ObjectID=lua_tonumber(L,2);
char PathBuffer[256]; wcstombs(PathBuffer,***EDITED FOR STATE SECRETS! LOL!***,256); string FullPath=PathBuffer; FullPath+="plugins\\Lunar\\scripts\\"; FullPath+=File;
PrimitiveObject *Target=FindPrimitiveObject(ObjectID);
if(Target==NULL) { char AliasBuffer[10]; itoa(ObjectID,AliasBuffer,10); lua_pushboolean(L,false); luaL_error(L,"Could not find primitive object %s in primitive_SetTexture.",AliasBuffer); } else { lua_pushboolean(L,true); ***LOL, MORE STATE SECRETS!*** } } } else { lua_pushboolean(L,false); luaL_error(L,"Null windower pointer in primitive_SetTexture."); } SDL_SemPost(GetSemaphore()); return 1; }
Heh, the lines talking about state secrets are where I took out the windower API lines. The first line is where I get the primitive pointer from the windower, and the second one is where I actually assign it a texture. I can't show you guys that of course. Its a state secret. At least now you can see where errors can come in. Thats alot of code just to set what essentially boils down to a file name on a primitive.
All lua wrapper functions like this look essentially the same. First I lock the library semaphore for thread safety. Then I get a windower instance pointer. If the pointer is good, I do whatever the function needs to do, and if its bad, I toss an error. Add some error checking to make sure the arguments are good, and you have a complete lunar function in C++! Repeat this about 100 times and you have the majority of the lunar library code. The lunar core code is so, so much worse.
|
|