Posts: 4,636
Threads: 115
Joined: Dec 2011
Thanks: 697
Given 505 thank(s) in 432 post(s)
10-22-2015, 04:50 PM
(This post was last modified: 10-22-2015, 04:50 PM by NiLSPACE.)
Isn't it possible to make the StringLenToASCII function dynamic?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | function StringLenToASCII(a_Player, a_String)
local template = ( "return \0\%s" ):format(a_String:len())
local loader = loadstring (template);
setfenv(loader, {});
local succes, res = pcall(loader)
if ( not succes) then
LOG( "The server name is incompatible with this plugin! Please make sure it is 30 characters or less!" );
Player:SendMessageFailure( "The server name is incompatible with this plugin! Please make sure it is 30 characters or less!" );
return false;
else
return res;
end
end
|
Or does it really matter because BungeeCord doesn't support longer or something?
Posts: 6,485
Threads: 176
Joined: Jan 2012
Thanks: 131
Given 1082 thank(s) in 854 post(s)
10-22-2015, 05:31 PM
(This post was last modified: 10-22-2015, 05:33 PM by xoft.)
How about a simple string.format with %c?
1 2 3 4 5 6 7 8 | local function writeProtocolString(a_Str)
local len = a_Str:len()
return string.format ( "%c%c%s" , math.floor (len / 256), math.floor (len % 256), a_Str)
end
client:SendPluginMessage( "BungeeCord" , writeProtocolString( "Connect" ) .. writeProtocolString( "SomeServer" ))
|
Posts: 4,636
Threads: 115
Joined: Dec 2011
Thanks: 697
Given 505 thank(s) in 432 post(s)
I didn't know you could do that with the percentage symbol, thanks
Posts: 66
Threads: 12
Joined: Oct 2015
Thanks: 0
Given 10 thank(s) in 8 post(s)
This is my second day of Lua programming. I have no idea how either of those work. I'm also going to bed now, so I won't be looking them up until morning. If they insert the number into the string before the \ escapes the following characters, then yes, they probably work and it's a great solution. If the \ is lost or the \# is interpreted as "\\" .. "#", then it wouldn't. I'm too tired to test it out now, but making a code snippet shouldn't take more than 3 minutes. All the needed code is somewhere in this thread.
Posts: 66
Threads: 12
Joined: Oct 2015
Thanks: 0
Given 10 thank(s) in 8 post(s)
(10-22-2015, 04:50 PM)NiLSPACE Wrote: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | function StringLenToASCII(a_Player, a_String)
local template = ( "return \0\%s" ):format(a_String:len())
local loader = loadstring (template);
setfenv(loader, {});
local succes, res = pcall(loader)
if ( not succes) then
LOG( "The server name is incompatible with this plugin! Please make sure it is 30 characters or less!" );
Player:SendMessageFailure( "The server name is incompatible with this plugin! Please make sure it is 30 characters or less!" );
return false;
else
return res;
end
end
|
(10-22-2015, 05:31 PM)xoft Wrote: 1 2 3 4 5 6 7 8 | local function writeProtocolString(a_Str)
local len = a_Str:len()
return string.format ( "%c%c%s" , math.floor (len / 256), math.floor (len % 256), a_Str)
end
client:SendPluginMessage( "BungeeCord" , writeProtocolString( "Connect" ) .. writeProtocolString( "SomeServer" ))
|
Finally got around to looking at these. Attempted both methods, trying xoft's first. String was improperly formed and led to kick by fake DC (same issue as when I was using \0\14 for a 5 digit string, so the string is being returned as "\0\\" .. "#" instead of "\0\#"). Attempted using %x and %u to identical results.
NilSPACE's function isn't even correct as far as I can tell. No idea how to use setfenv, so yeah.
Code: [03:27:53] LUA: Plugins/BungeeButtons/main.lua:40: bad argument #1 to 'setfenv'
(number expected, got nil)
[03:27:53] Stack trace:
[03:27:53] [C](-1): setfenv
[03:27:53] Plugins/BungeeButtons/main.lua(40): StringLenToASCII
[03:27:53] Plugins/BungeeButtons/main.lua(188): (no name)
[03:27:53] Stack trace end
[03:27:53] Error in plugin BungeeButtons calling function <callback>()
I tried altering it... a lot of ways actually, but the best result was this one:
1 2 3 4 5 | function StringLenToASCII(a_Player, a_String)
local template = ( "return '\0\%s'" ):format(a_String:len())
local loader = loadstring (template);
return assert (loader, "weird ass error" )()
end
|
but it just returns "\0\\" .. "#", which won't work. Also tried with %u to identical results (the fake offline kick).
BACK TO THE ARRAY OF VALUES!
Also I don't WANT to use the array of values. I'm currently working on a plugin that could send plugin messages of incredible lengths (like 200+ characters) and that doesn't sound super fun to make an array for. It's just, if a method can't be found, I'll have to.
I'll probably ask on stackoverflow at some point.
Posts: 6,485
Threads: 176
Joined: Jan 2012
Thanks: 131
Given 1082 thank(s) in 854 post(s)
10-25-2015, 01:45 AM
(This post was last modified: 10-25-2015, 01:46 AM by xoft.)
Ah, so it's Lua's fault, its string.format function doesn't handle embedded NULs properly: http://www.lua.org/manual/5.1/manual.htm...ing.format
Posts: 6,485
Threads: 176
Joined: Jan 2012
Thanks: 131
Given 1082 thank(s) in 854 post(s)
This piece of code should work:
1 2 3 4 5 6 7 8 | local function writeProtocolString(a_Str)
local len = a_Str:len()
return string.char ( math.floor (len / 256), math.floor (len % 256)) .. a_Str
end
client:SendPluginMessage( "BungeeCord" , writeProtocolString( "Connect" ) .. writeProtocolString( "SomeServer" ))
|
Posts: 66
Threads: 12
Joined: Oct 2015
Thanks: 0
Given 10 thank(s) in 8 post(s)
That worked. So happy there's a way to do this.
So, using the floored calculations, I assume, is needed because of something either later in cuberite's translating of the packet, or in BungeeCord's translation (or both). My question, though, is, do strings over 256 still work, then? And if they do, that means the format would be \1\(string-256) before 512 characters. Thank god this topic happened because I never would have thought to use that string for lengths over 256.
Posts: 6,485
Threads: 176
Joined: Jan 2012
Thanks: 131
Given 1082 thank(s) in 854 post(s)
The math.floor calls are necessary, Lua would round the numbers otherwise and thus breaking the format for example for length 255 (string.byte(255/256) == "\1" instead of the needed "\0"). This code should work for all string lengths up to 64K, which is the packet's maximum.
Posts: 6,485
Threads: 176
Joined: Jan 2012
Thanks: 131
Given 1082 thank(s) in 854 post(s)
Another possibility would be to use this line instead:
1 | return string.char ((len - 127) / 256), len % 256) .. a_Str
|
|