Author Topic: Universal GUI API  (Read 1821 times)

This is an idea I've been floating around in my head for a couple of years now. It's always a bit irking to have to download an add-on for, say, an RPG server and assign its GUI it's own, unique keybind. Frankly, it seems a bit unnecessary. Is there anything stopping us from creating some sort of API that standardizes GUI creation? For instance, a player could use the same assigned keybind for any server with this add-on to open up that particular server's GUI of choice. Information regarding the GUI's layout and functionality could be communicated to clients via JSON, XML, or something similar. Think of how web servers comunicate with clients (i.e. HTML/CSS). Concievably, any gamemode could utilized this API so that incoming users wouldn't have to download a special add-on just to use that server's/gamemode's GUI. Perhaps this could even be something that could be implemented into something like Blockland Glass (but maybe I'm getting a bit ahead of myself).

I am not that familiar with GUIs, so some input from those more experienced with GUIs would be much appreciated. I wouldn't be suprised if I'm not the first to think of this idea.
« Last Edit: May 21, 2017, 12:02:17 AM by Platypi »

mission editor in a sense is this. i dont have a link to a dl rn, but if you do get your hands on it iirc f5 or f12 opens up the gui editor.

for clarification mission editor to bl/other torque games is kinda like source filmmaker/engine to tf2.

mission editor in a sense is this. i dont have a link to a dl rn, but if you do get your hands on it iirc f5 or f12 opens up the gui editor.

for clarification mission editor to bl/other torque games is kinda like source filmmaker/engine to tf2.

I think he's talking more about sending GUI data to clients instead of making them download the add-on first

With the way GUIs work in Blockland something like this wouldn't really be too helpful. If all you could do is create gui controls and menus for people with no code attached with it, the functionality would be pretty bare. The closest thing to this that we have is the "required clients" portion of Blockland Glass which hasn't really been used very much, but it basically prompts people to download an add-on and will download and execute it automatically before connecting (documentation in the manual).

I do agree that having one central key bind would be cool, having tons of binds for various servers is annoying. I like how Garry's Mod leaves F1-4 as spares.

The closest thing to this that we have is the "required clients" portion of Blockland Glass which hasn't really been used very much, but it basically prompts people to download an add-on and will download and execute it automatically before connecting (documentation in the manual).
i didn't even know glass had that but now that i know it does i really hope it sees more widespread adoption so that feature can see some use

but yeah, it's not really practical to involve the server in directly sending GUI data unless you can make a really sophisticated infrastructure that's capable of accomplishing way more out-of-the-box purely with clientCmds, and even then you would have to assume that every client has the mod to enable that functionality. it'd be much better to let an intermediate service like glass moderate the needed client mods and allow server hosts to automatically prompt clients to download the mod, because then server hosts get full control on the client side, and clients get assurance that the code they download is safe. the idea of having universal keybinds is really neat though, it'd be cool to see smth like that

So, this is actually what Blockland Glass was originally (2012) and I've thought about re-implementing this in a new innovative way in a future update. Many have dismissed it as unfeasible but it's actually very do-able. The downside of this old implementation is that it's not very kind to developers, but I believe I have a remedy to that. Could make an appearance in Glass 4.2

I think he's talking more about sending GUI data to clients instead of making them download the add-on first
This is correct. I am have been acquainted with the mission editor; although it has been some years since I last used it. To be more precise, though, they would only have to download a single add-on once.

With the way GUIs work in Blockland something like this wouldn't really be too helpful. If all you could do is create gui controls and menus for people with no code attached with it, the functionality would be pretty bare.
Again drawing an brown townogy with web development, think of how HTML forms work. An HTML page can include a button that, when clicked, sends a POST request to the web server. In the spirit of this idea, the GUI layout that a server sends a player with this mod would include the server command (i.e. serverCmd____) that will be send to the server when clicking a particular button.

The closest thing to this that we have is the "required clients" portion of Blockland Glass which hasn't really been used very much, but it basically prompts people to download an add-on and will download and execute it automatically before connecting (documentation in the manual).
This could be good enough. Would probably work the same. I'll look into it later.

I like how Garry's Mod leaves F1-4 as spares.
I think this is where I got the idea from. Why shouldn't GUIs in Blockland load like GUIs in Gmod?

clients get assurance that the code they download is safe.
Honestly, I would be more wary about downloading a client than using a prexisting API. It would depend, however, on how much functionality the GUI API would be given. If we tried to implement some kind of JS into it, security concerns would be higher given it would be automatically run. However, if the GUI API simply sends over a GUI layout with some info regarding what server commands each button sends, then I can't really see how this would be more of a security risk.

So, this is actually what Blockland Glass was originally (2012) and I've thought about re-implementing this in a new innovative way in a future update. Many have dismissed it as unfeasible but it's actually very do-able. The downside of this old implementation is that it's not very kind to developers, but I believe I have a remedy to that. Could make an appearance in Glass 4.2
That's good to hear! I was certain someone else had already thought of this before. What you say about this not being friendly to developers is my main concern, too. I would like developers to be able to continue using the mission editor to create GUIs. However, if we just arbitrarily send GUI code to a user, that could pose a huge security risk (I think this is what otto-san is specifically concerned about). Perhaps there would be a way to sandbox the GUI code? Would converting everything to XML, JSON, etc. on the server-side and then back again on the client-side be feasible (i.e. not drive the people developing the GUI API insane)? These are my primary concerns at this stage.

If you have some code you'd be cool with sharing, I would love to see it. Post it here, or PM me.

I may try to get a proof-of-concept working by the end of the week. I'll try to upload a video to accompany it. Hopefully it will help clear up some confusion on exactly what I'm proposing.


Again drawing an brown townogy with web development, think of how HTML forms work. An HTML page can include a button that, when clicked, sends a POST request to the web server. In the spirit of this idea, the GUI layout that a server sends a player with this mod would include the server command (i.e. serverCmd____) that will be send to the server when clicking a particular button.

Too high latency. If you click on a button to do something, you expect something to happen now not a quarter of a second later.
Basically every gui application ever runs the gui code locally for that reason.

Honestly, I would be more wary about downloading a client than using a prexisting API. It would depend, however, on how much functionality the GUI API would be given. If we tried to implement some kind of JS into it, security concerns would be higher given it would be automatically run. However, if the GUI API simply sends over a GUI layout with some info regarding what server commands each button sends, then I can't really see how this would be more of a security risk.
a sophisticated API to construct client mods on the client-side would be theoretically more safe, yes. however, it would be much less flexible, require a significant amount of infrastructure, and require modders to practically learn how to work an entirely new GUI system. there would be very little incentive for modders to choose an option like this when the option of simply requiring a client mod, which the modder can create in pure TS with the aid of vanilla tools, is available and made even simpler with a moderated add-on distribution system.

and, of course, if there were a vulnerability in the API somewhere, it would be incredibly trivial for server hosts to abuse it without any form of informed consent from the client

Too high latency. If you click on a button to do something, you expect something to happen now not a quarter of a second later.
Basically every gui application ever runs the gui code locally for that reason.
It would depend on the application. For instance, if it was just simple item store where you click a button to buy an item, each button press would have to communicate with the server anyway. The latency would be about the same as it would be if the GUI was implemented as a seperate client add-on. However, I could see how, say, a calculator would be a bit irking to use.

Since we would want to make this GUI API as widely applicable as possible, so I suppose we would have to have some way to send code to the user. We'll probably have to figure out how to put the code in some sort of sandbox so it wouldn't have access to everything. Perhaps we could make it so that a server that uses this API would have to request client permission for differnt sorts of asks. So when a client joins a server, they are given prompt asking whether they are fine with the server having access to a certain list of permissions (e.g. reading or writing to config). Think of when you are downloading an app on your phone and it warns you about what permissions the app will demand before you download it. But even if we just ran code arbirarily (i.e. without a sandbox) after receiving consent from the user, it wouldn't be any less secure than any other client add-on.

a sophisticated API to construct client mods on the client-side would be theoretically more safe, yes. however, it would be much less flexible, require a significant amount of infrastructure, and require modders to practically learn how to work an entirely new GUI system. there would be very little incentive for modders to choose an option like this when the option of simply requiring a client mod, which the modder can create in pure TS with the aid of vanilla tools, is available and made even simpler with a moderated add-on distribution system.

and, of course, if there were a vulnerability in the API somewhere, it would be incredibly trivial for server hosts to abuse it without any form of informed consent from the client
The logistics certainly seem to increase as more functionality is considered. Duly, one abused vulnerablity could lead many to get cold feet and abandon the add-on outright. We could limit the application of the API. But if we can't create a GUI API that works for virtually all applications, there's really no use in making it at all. I think I'm still going to toy around with the idea, though.

I would still very much like to avoid having to use a unique keybind for every server that uses a client add-on. Perhaps Blockland Glass could include a few action keybinds (like Gmod's F1-F4 keys, as per Crøwn) that mods could utilize. I don't think it would be particularly difficult. They could probably have a wider application than just opening menus, too. It could be as simple as binding a function like BLGActionKey1() and packaging it in a client add-on, and/or binding commandToServer("BLGActionKey1") to a keybind and packaging serverCmdBLGActionKey1() for server-sided add-ons.

My original implementation of this came along with a 'bind manager' which would prompt you for server-specific keybinds and save them, but I think setting global generics would be a better solution. I don't recall latency being a huge problem, though I expect it would be on a crowded server.

A general implementation would've looked like the following:

Code: [Select]
exec("./myGui.gui");
// myGui has a GuiBitmapButtonCtrl called myButton
// myGui has a GuiTextEditCtrl called myText

%do = BLG_GDS.registerObject(myGui);
%do.registerCloseHandler("myCloseMethod");

%buttonDO = BLG_GDS.getDataObject(myButton);
%buttonDO.registerHandler("buttonPressMethod");

function myCloseMethod(%client, %do) {
  messageAll('', %client.netname @ " closed the gui!");
}

function buttonPressMethod(%client, %do) {
  %inputDO = BLG_GDS.getDataObject(myText);
  %val = %inputDO.getValue(%client);

  %inputDO.setValue(%client, ""); //reset input to blank

  messageAll('', %client.netname @ " typed " @ %val);
}



What makes it problematic is constantly having to deal with "DataObjects", a sort of wrapper class that represents a GUI element. I'd like to (if I were to implement this again) switch over to using the GuiControl's themselves instead of a wrapper class. Something like the following:

Code: [Select]
exec("./myGui.gui");
// myGui has a GuiBitmapButtonCtrl called myButton
// myGui has a GuiTextEditCtrl called myText

myGui.enableTransfer(); //set gui to be sent to clients

myGui.addCloseCallback("myCloseMethod");
myButton.addCallback("buttonPressMethod");

function myCloseMethod(%client, %obj) {
  messageAll('', %client.netname @ " closed the gui!");
}

function buttonPressMethod(%client, %obj) {
  %val = myText.getValue(%client);
  myText.setValue(%client, "");

  messageAll('', %client.netname @ " typed " @ %val);
}

I believe this is a lot easier to work with and makes the code very similar to client code, with the only difference being the %client argument being added in to pretty much everything. This may actually be easier for some devs who aren't so savvy with all the commandToClient/commandToServer stuff. I don't think the code complexity is very far beyond just writing the client. Of course, a full client is able to still do more, but having personalized, interactable GUI and HUD elements covers a lot of cases - stores, CityRPG status bars, buy/sell dialogs. I believe my original test-case was to remake the Rise of Blockland GUI and I believe it wasn't all that difficult (and I was ~14 at the time).

Perhaps also adding functionality for a few commonly used actions, such as a button closing/opening another gui element, toggling visibility, submitting and clearing a text field, etc. This would remove a lot of cases where server lag would ruin the experience.

« Last Edit: May 21, 2017, 08:36:52 PM by Scout31 »

I do agree that having one central key bind would be cool, having tons of binds for various servers is annoying. I like how Garry's Mod leaves F1-4 as spares.
I tried that years ago as an addon.

I tried that years ago as an addon.
What was the problem? I'd assume it was mainly that the add-on didn't get enough traction, which shouldn't be a problem with BLG. Or was it a functional problem?