ServerGS - Access the GS API from the admin port

Discuss the new AI features ("NoAI") introduced into OpenTTD 0.7, allowing you to implement custom AIs, and the new Game Scripts available in OpenTTD 1.2 and higher.

Moderator: OpenTTD Developers

Post Reply
User avatar
Zuu
OpenTTD Developer
OpenTTD Developer
Posts: 4553
Joined: 09 Jun 2003 18:21
Location: /home/sweden

ServerGS - Access the GS API from the admin port

Post by Zuu »

This is a special Game Script that doesn't do anything on its own. Instead it expose the Game Script API to Admin Port clients.

Compatible OpenTTD versions: stable >=1.3.3 and nightly >=25810

Using this GS as a bridge you can:
  • Call API methods
  • Make use of enum constants in the API (so that you don't need to hard code their integer values in your client)
  • Literal arguments can also be used (integer and strings)
  • Create eg. GSTownList() and get a JSON array back with all town IDs
  • Via special parameter specify if GSCompanyMode and/or GSTestMode should be active in scope when calling the API method
  • Receive a message with the event when users answer the question dialog opened with GSGoal.Question
  • Call SuperLib.Story.* methods (4 at the moment)
What you cannot do:
  • Pass callback methods to APIs that accept that (mainly valuators)
  • Use GSList APIs that require that you first create a list instance and then call member functions of the list instance.
  • Use GSAccountingMode (would be easy to add, but I don't see any use case for it)
  • No generic support for *all* events yet
It is quite easy to add a few additional functions from SuperLib or other libraries. However, if *all* are going to be added, I need to write a script for that too which is possible a bit more tricky than parsing the .sq files in the OpenTTD source code which follows a fairly strict pattern.

The only method in the API classes that I haven't included is GSController.import as it is a hidden method not available for scripts to use. It may be that some of the methods included may not be useful or good to use. You can even use GSAdmin.Send to send messages, only problem is that currently tables are not listed as accepted argument types (which would be a quite simple change to allow if you may need it).

For further information, I suggest that you read the readme.txt file which contains quite a bit of information on how to format requests to ServerGS and what response messages that you can expect.


The script is GPLv2, but I would be happy if you contribute back patches if you make improvements to the script even if you don't share the script.

Edit:
- Link to readme.txt
- Repository can be found here: http://dev.openttdcoop.org/projects/gs- ... repository
- Version 2 also supports stable (1.3.3+)
Attachments
ServerGS-v2.tar
(310 KiB) Downloaded 482 times
My OpenTTD contributions (AIs, Game Scripts, patches, OpenTTD Auto Updater, and some sprites)
Junctioneer (a traffic intersection simulator)
User avatar
Zuu
OpenTTD Developer
OpenTTD Developer
Posts: 4553
Joined: 09 Jun 2003 18:21
Location: /home/sweden

Re: ServerGS - Access the GS API from the admin port

Post by Zuu »

Version 2

This version also contains API symbols generated from OpenTTD 1.3.2. (note that the API in 1.3.3 is the same as in 1.3.2)

However, I suggest however not to use version 2 in 1.3.2, but upgrade your server to 1.3.3 because it fixes a bug that otherwise make it impossible to via JSON call API methods with zero parameters.


The script will automatically detect if you use a new enough nightly so that you can use the nightly API or if it will fallback to the 1.3 API.
My OpenTTD contributions (AIs, Game Scripts, patches, OpenTTD Auto Updater, and some sprites)
Junctioneer (a traffic intersection simulator)
krinn
Transport Coordinator
Transport Coordinator
Posts: 339
Joined: 29 Dec 2010 19:36

Re: ServerGS - Access the GS API from the admin port

Post by krinn »

Going to make it a lib or not Zuu ? :)
User avatar
Zuu
OpenTTD Developer
OpenTTD Developer
Posts: 4553
Joined: 09 Jun 2003 18:21
Location: /home/sweden

Re: ServerGS - Access the GS API from the admin port

Post by Zuu »

For review - upcoming version 3

I have separated the core into a library and now produced both a library and a GS so that the library can be used by other Game Scripts. Before publishing a final version and uploading to bananas I publish these for review.

The library need to get events from the GS using it. Currently you must call LibServerGS.ReceiveEvent(event) yourself. I know that it is possible for a library to hook into the event system to read events before the GS get hand of it. However - personally I find the GS code more readable if there is an explicit call to pass the event on to the libraries used.

I am thinking about possible renaming LibServerGS to LibAdminPort or similar but not sure yet.


Documentation for GS authors
Please see the readme in LibServerGS and section 4 on how the library is added to a GS.

Exposed API methods
Thanks to a hint from krinn this version will not need an update when a new OpenTTD API is added. However it do come with the cost that the GS library cannot detect if a call will fail due to wrong parameter count or wrong data types. This can in my tests cause the GS to crash. Thus it means that this GS is less friendly to Admin Port client developers that may by mistake make a bad call and then need to restart/reload the game.

If someone has a solution on how to catch these errors either by somehow via Squirrel interface read this information or catch the error when it occurs. (I do have a try-catch that will catch some other errors but doesn't catch these two errors)
Attachments
LibServerGS-v3.tar
The library

Requires SuperLib 36
(60 KiB) Downloaded 348 times
ServerGS-v3.tar
The game script

Requires SuperLib 36
(40 KiB) Downloaded 320 times
My OpenTTD contributions (AIs, Game Scripts, patches, OpenTTD Auto Updater, and some sprites)
Junctioneer (a traffic intersection simulator)
krinn
Transport Coordinator
Transport Coordinator
Posts: 339
Joined: 29 Dec 2010 19:36

Re: ServerGS - Access the GS API from the admin port

Post by krinn »

I'm sad the lib import SuperLib, so putting a dep on superlib for a program that might not use it.
I would had prefer the lib doesn't pull that dependency itself, but reuse existing one it can find if the program have it.
The few functions from superlib the library need could have been merge with the lib.

Code: Select all

if ("SuperLib" in _LibServerGS_private_const_root_class) {
	// Detect if loaded SuperLib is >= version 36.
	if (!("HasWorldGenBug" in SuperLib.Helper)) {
		Log.Error("LibServerGS want to have SuperLib 36 or later. An older version was detected.");
		throw false;
	LibServerGS.AddAllowRootExactMatch("SuperLib"); // allow superlib symbols if we're link with a program using superlib
}
I don't think the library need any support for "Story". Using "Story"->"SuperLib.Story" can only be found in v1 and v2, but the library itself isn't use by v1 and v2.
If people use v1|v2 they don't use the library, and if people use the lib or v3, they should use "SuperLib.Story". Removing confusion.
The compatibility layer add a shortcut, not compatibility.
So i would start with :

Code: Select all

	static _allowed_root_exact_match = []; // Story drop, SuperLib autoadd on detection
krinn
Transport Coordinator
Transport Coordinator
Posts: 339
Joined: 29 Dec 2010 19:36

Re: ServerGS - Access the GS API from the admin port

Post by krinn »

Zuu wrote:Thus it means that this GS is less friendly to Admin Port client developers that may by mistake make a bad call and then need to restart/reload the game.

If someone has a solution on how to catch these errors either by somehow via Squirrel interface read this information or catch the error when it occurs. (I do have a try-catch that will catch some other errors but doesn't catch these two errors)
I think it's worth the lost vs no new version out.
You expose API to adminport, upto the adminport author to use it as it should. And wrong usage of them thru admin port gave no more no less what openttd gave to wrongly using them with a GS/AI.
User avatar
Zuu
OpenTTD Developer
OpenTTD Developer
Posts: 4553
Joined: 09 Jun 2003 18:21
Location: /home/sweden

Re: ServerGS - Access the GS API from the admin port

Post by Zuu »

krinn wrote:I'm sad the lib import SuperLib, so putting a dep on superlib for a program that might not use it.
I would had prefer the lib doesn't pull that dependency itself, but reuse existing one it can find if the program have it.
The library will use the SuperLib imported by GS if the GS import SuperLib before LibServerGS.

The library use some methods from SuperLib and I think it is sound to not inline those as that defeats the main purpose of SuperLib - only fix the same bug once.

In the library, I could import SuperLib 36 as some non-standard name or only to the Library scope, and use that internally. Then expose to Admin Port only stuff that the client GS has imported to the global scope.
krinn wrote:I don't think the library need any support for "Story". Using "Story"->"SuperLib.Story" can only be found in v1 and v2, but the library itself isn't use by v1 and v2.
If people use v1|v2 they don't use the library, and if people use the lib or v3, they should use "SuperLib.Story". Removing confusion.
What I cared about was people who may have written a program that want to support ServerGS 1-3. If 'Story' is dropped, there is no equal way to access Story in both 1-2 and 3.

That said, it may be better to leave this out of the library and only do so in the GS. However, I think it is useful to have a base level of support that a admin port client can expect to find. I'm not exactly sure if Admin Port is subject to package delivery in wrong order, but if that is the case - then a higher level Story method is useful if you want to display messages to clients. These messages lack translation of course and is not the same as having a fully fledged GS but then ServerGS is not a replacement to a GS written in Squerrel.

Having a common base level was the reason why this is included in the library - and that possible we value the cost of including a library differently.
My OpenTTD contributions (AIs, Game Scripts, patches, OpenTTD Auto Updater, and some sprites)
Junctioneer (a traffic intersection simulator)
krinn
Transport Coordinator
Transport Coordinator
Posts: 339
Joined: 29 Dec 2010 19:36

Re: ServerGS - Access the GS API from the admin port

Post by krinn »

Zuu wrote: The library will use the SuperLib imported by GS if the GS import SuperLib before LibServerGS.
Yes, but also import SuperLib if it cannot find it, that's the problem.
The library use some methods from SuperLib and I think it is sound to not inline those as that defeats the main purpose of SuperLib - only fix the same bug once.
This makes sense for big project you handle, not for a library that should have its code frozen.

If i link my program with the library, and i use SuperLib myself, it's great, the library will use the one from the program, so all its functions are now running the update version of SuperLib my program is using. No problemo.
But if i link a program that doesn't use SuperLib : now the library import SuperLib version 36, and content download will always get v36 as dependency : no more update code, and a dependency version that will get old soon.

So, in order to keep an update SuperLib version for this lib for a program that don't use SuperLib, you will be force to update the library too.
All this for what? Having latest SuperLib version in use, but the program itself still don't use it.

I agree Story makes sense for admin port tools compatibility that are using it, but that could be done by the GS, not handle by the lib itself.
But i could live with extra symbol and handling of Story, but SuperLib trouble me more.

If i build a GS with SuperLib, it will be a great addition.
But if i build a GS without SuperLib, the addition of SuperLib will grant nothing to my program, i just see that as adding bloat for no reason (not that SuperLib is bloat for me, but it's a huge library, and if you don't use it, any extra lines that have no usage are just bloat).

That lib is great, as anyone making a GS need just to import it and add the event handling and admin tools have access to GS API.
Even better, your GS can add some functions for the admin port and expose them too (like a function that return stats...).

That library should be use by all GS authors : it's a little addition in their code, for a great benefit : the lib itself gave high capability to server owner. Something any GS author should expect their GS to run on.
But "the little addition" for a GS that doesn't use SuperLib is no more something i would see as "little".

It's your library ; your work, if you really want link it with SuperLib, fine. It will be a great library for GS using SuperLib. I think it could have been the same for GS that doesn't use SuperLib. Making it a mandatory library for any GS.
User avatar
NewGRF
Engineer
Engineer
Posts: 11
Joined: 04 Apr 2017 02:36

Re: ServerGS - Access the GS API from the admin port

Post by NewGRF »

error
Attachments
2017-11-28_190644.jpg
2017-11-28_190644.jpg (276.34 KiB) Viewed 2424 times
svermaak
Engineer
Engineer
Posts: 8
Joined: 02 Oct 2017 14:44

Re: ServerGS - Access the GS API from the admin port

Post by svermaak »

NewGRF wrote:error
I get the same error :(
rknetwork
Engineer
Engineer
Posts: 8
Joined: 31 Jan 2013 13:44

Re: ServerGS - Access the GS API from the admin port

Post by rknetwork »

Hello everyone,

I'm getting this error, does anyone know what the problem is?
Ping and other calls are working fine.

Code: Select all

dbg: [net] [admin] GameScript JSON from 'php' (1): '{"action":"call","method":"GSGoal.Question","args":[0,"GSCompany.COMPANY_INVALID","\"Hello the admin is speaking\"","GSGoal.QT_INFORMATION","GSGoal.BUTTON_OK | GSGoal.BUTTON_CANCEL"]}'

dbg: [script] [18] [S] Your script made an error: the index 'symbol' does not exist
dbg: [script] [18] [S]
dbg: [script] [18] [S] *FUNCTION [Eval()] libservergs-v3/main.nut line [294]
dbg: [script] [18] [S] *FUNCTION [ReceiveAdminPortMessage()] libservergs-v3/main.nut line [216]
dbg: [script] [18] [S] *FUNCTION [ReceiveEvent()] libservergs-v3/main.nut line [150]
dbg: [script] [18] [S] *FUNCTION [HandleEvents()] /usr/home/openttd/.openttd/content_download/game/ServerGS-v3/main.nut line [127]
dbg: [script] [18] [S] *FUNCTION [Start()] /usr/home/openttd/.openttd/content_download/game/ServerGS-v3/main.nut line [85]
dbg: [script] [18] [S]
dbg: [script] [18] [S] [sym] -1
dbg: [script] [18] [S] [@ITERATOR@] 1
dbg: [script] [18] [S] [or_part] "GSCompany.COMPANY_INVALID"
dbg: [script] [18] [S] [@INDEX@] 0
dbg: [script] [18] [S] [or_parts] ARRAY
dbg: [script] [18] [S] [str] "GSCompany.COMPANY_INVALID"
dbg: [script] [18] [S] [arg_value] 0
dbg: [script] [18] [S] [@ITERATOR@] 2
dbg: [script] [18] [S] [arg] "GSCompany.COMPANY_INVALID"
dbg: [script] [18] [S] [@INDEX@] 1
dbg: [script] [18] [S] [arg_num] 2
dbg: [script] [18] [S] [arg_values] ARRAY
dbg: [script] [18] [S] [func] NATIVECLOSURE
dbg: [script] [18] [S] [args] ARRAY
dbg: [script] [18] [S] [call] "GSGoal.Question"
dbg: [script] [18] [S] [this] INSTANCE
dbg: [script] [18] [S] [tm] NULL
dbg: [script] [18] [S] [cm] NULL
dbg: [script] [18] [S] [response] TABLE
dbg: [script] [18] [S] [data] TABLE
dbg: [script] [18] [S] [this] INSTANCE
dbg: [script] [18] [S] [data] TABLE
dbg: [script] [18] [S] [admin_event] INSTANCE
dbg: [script] [18] [S] [ev_type] 24
dbg: [script] [18] [S] [event] INSTANCE
dbg: [script] [18] [S] [this] INSTANCE
dbg: [script] [18] [S] [ev] INSTANCE
dbg: [script] [18] [S] [this] INSTANCE
dbg: [script] [18] [S] [this] INSTANCE
rknetwork
Engineer
Engineer
Posts: 8
Joined: 31 Jan 2013 13:44

GSCompany.GetName error when calling from Admin Port

Post by rknetwork »

Hello everyone,

I'm getting this error when trying to send a message through Admin Port.

Please help.

Code: Select all

dbg: [net] [admin] GameScript JSON from 'Liberty Admin' (1): '{"action":"call","method":"GSCompany.GetName","args":[42,"GSGoal.BUTTON_OK","\"A message from Admin\"","other string"]}'
dbg: [script] [18] [S] Your script made an error: the index 'symbol' does not exist
dbg: [script] [18] [S] 
dbg: [script] [18] [S] *FUNCTION [Eval()] libservergs-v3/main.nut line [294]
dbg: [script] [18] [S] *FUNCTION [ReceiveAdminPortMessage()] libservergs-v3/main.nut line [216]
dbg: [script] [18] [S] *FUNCTION [ReceiveEvent()] libservergs-v3/main.nut line [150]
dbg: [script] [18] [S] *FUNCTION [HandleEvents()] servergs-v3/main.nut line [127]
dbg: [script] [18] [S] *FUNCTION [Start()] servergs-v3/main.nut line [85]
dbg: [script] [18] [S] 
dbg: [script] [18] [S] [sym] 2
dbg: [script] [18] [S] [@ITERATOR@] 1
dbg: [script] [18] [S] [or_part] "GSGoal.BUTTON_OK"
dbg: [script] [18] [S] [@INDEX@] 0
dbg: [script] [18] [S] [or_parts] ARRAY
dbg: [script] [18] [S] [str] "GSGoal.BUTTON_OK"
dbg: [script] [18] [S] [arg_value] 0
dbg: [script] [18] [S] [@ITERATOR@] 2
dbg: [script] [18] [S] [arg] "GSGoal.BUTTON_OK"
dbg: [script] [18] [S] [@INDEX@] 1
dbg: [script] [18] [S] [arg_num] 2
dbg: [script] [18] [S] [arg_values] ARRAY
dbg: [script] [18] [S] [func] NATIVECLOSURE
dbg: [script] [18] [S] [args] ARRAY
dbg: [script] [18] [S] [call] "GSCompany.GetName"
dbg: [script] [18] [S] [this] INSTANCE
dbg: [script] [18] [S] [tm] NULL
dbg: [script] [18] [S] [cm] NULL
dbg: [script] [18] [S] [response] TABLE
dbg: [script] [18] [S] [data] TABLE
dbg: [script] [18] [S] [this] INSTANCE
dbg: [script] [18] [S] [data] TABLE
dbg: [script] [18] [S] [admin_event] INSTANCE
dbg: [script] [18] [S] [ev_type] 24
dbg: [script] [18] [S] [event] INSTANCE
dbg: [script] [18] [S] [this] INSTANCE
dbg: [script] [18] [S] [ev] INSTANCE
dbg: [script] [18] [S] [this] INSTANCE
dbg: [script] [18] [S] [this] INSTANCE
Untitled.png
Untitled.png (19.19 KiB) Viewed 7206 times
sszretter
Engineer
Engineer
Posts: 1
Joined: 01 Jun 2021 14:40

Re: ServerGS - Access the GS API from the admin port

Post by sszretter »

I know this is old but did you figure this out? I have the same issue
Post Reply

Return to “OpenTTD AIs and Game Scripts”

Who is online

Users browsing this forum: No registered users and 6 guests