Attempting to get Bungeecord Teleportation Functional
#11
Isn't it possible to make the StringLenToASCII function dynamic?
function StringLenToASCII(a_Player, a_String)
	local template = ("return \0\%s"):format(a_String:len())
	local loader = loadstring(template);
	
	-- Sandbox the loader
	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?
Reply
Thanks given by:
#12
How about a simple string.format with %c?
--- Returns the string prefixed with its length, as used in the BungeeCord protocol
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

-- usage:
client:SendPluginMessage("BungeeCord", writeProtocolString("Connect") .. writeProtocolString("SomeServer"))
Reply
Thanks given by:
#13
I didn't know you could do that with the percentage symbol, thanks Smile
Reply
Thanks given by:
#14
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.
Reply
Thanks given by:
#15
(10-22-2015, 04:50 PM)NiLSPACE Wrote:
function StringLenToASCII(a_Player, a_String)
	local template = ("return \0\%s"):format(a_String:len())
	local loader = loadstring(template);
	
	-- Sandbox the loader
	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:
--- Returns the string prefixed with its length, as used in the BungeeCord protocol
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

-- usage:
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:
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.
Reply
Thanks given by:
#16
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
Reply
Thanks given by:
#17
This piece of code should work:
--- Returns the string prefixed with its length, as used in the BungeeCord protocol
local function writeProtocolString(a_Str)
  local len = a_Str:len()
  return string.char(math.floor(len / 256), math.floor(len % 256)) ..  a_Str
end
 
-- usage:
client:SendPluginMessage("BungeeCord", writeProtocolString("Connect") .. writeProtocolString("SomeServer"))
Reply
Thanks given by:
#18
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.
Reply
Thanks given by:
#19
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.
Reply
Thanks given by:
#20
Another possibility would be to use this line instead:
return string.char((len - 127) / 256), len % 256) .. a_Str
Reply
Thanks given by:




Users browsing this thread: 1 Guest(s)