The client code has been checked-in to the SVN-repository. It isn't exactly the code used for the old C++-client, because some third-party code (copyright issues) was replaced with my own .NET classes. Therefore, it doesn't work ATM :rofl:.
Anyway, it compiles fine and demonstrates the future step into the managed direction by using mixed-mode approaches. Additionally, it shows the use of common classes (server and client both will use e.g. the NTP-client class) in order to reduce maintenance workload.
I've checked in kind of a patchbomb to the SVN repo. It's the beginning of the user interface conversion to .NET . Might be interesting for those folks wanting to use WindowsForms in Orbiter even with fullscreen.
On a side note: I'm working with Mercurial at home, so don't be surprised by many checkins happening shortly after each other. If you're interested in a Mercurial mirror of the SVN repo, let me know.
The OMP code repository moved from SVN (Subversion) at SourceForge to HG (Mercurial) at BitBucket. The website at SF contains a second pointer (besides the pointer to the old ugly homepage) to the appropriate Mercurial repository on BB.
I've additionally forked off the ORRL (Orbiter Rocket Racing League) branch from OMP. The appropriate links are:
Version 0.7.3 has been tagged and pushed to BitBucket here. This version fixes some bugs in the fast vessel class lane and primarily comes with a missile toy to test the former.
Changes since 0.7.2:
OMPClient: fixed bug in superstructure detection for unkown and tracking vessels
OMPMissile: added first draft of missile vessel
OMPMissile: front fins changed, engine port added and length changed to 3.7m
OMPClient: fixed crash on deleting unknown or tracked vessels
OMPMissile: added first draft of DLL for missile
VesselHook: added key handler infrastructure for built-in key-stroke commands
OMPClient: implemented key handler with missile launch and target functions
OMPClient: implemented missile target visualization and customization features
OMPMissile: implemented simple seeker algorithm
OMPMissile: implemented collision detection and explosion feature
OMPMissile: explode 10 seconds after MECO
OMPMissile: set orientation on every time step
OMPMissile: scale explosion particles according to target size
Host: fix fast lane for vessel class transmission
The missile is approximating an AIM120 missile, although I'm pretty sure that the developers of OBSP will find all kinds of mistakes in my sloppy implementation. It is just a toy, folks, please forgive me .
Many thanks to another new contributor to the project: RacerX. Thanks for the lean and mean mesh!
The weapons system implemented by the OMP client is generic, so you can use it with every VESSEL2 vessel (which should be almost everything now). You can customize it with client commands (prefixed with '%' like so:
%help will list "missile" as valid command
%missile will show all the available sub-commands
%state will show current missile parameters
%missile offset <x> <y> <z> sets the offset of the missile launch point, i.e. the point from the center of your current vessel where the missile will spawn on launch
%missile keys <launch> <target> <modifiers> sets the keys used for missile launch and target, as well as the modifiers for these keys - all values are hexadecimal, consult OAPI key values. Modifiers is a bitmap of left Shift (LSB), right Shift, left Ctrl, right Ctrl, left Alt, right Alt (MSB), so the default Left Ctrl+Alt modifier is 010100 binary, and 14 in hex. Default launch key is space, default target key is Enter.
%missile display <size> <x> <y> sets the missile target display size and offset. I use screen annotations instead of HUD hooking for marking the target on screen, so you may have to adjust the size and offsets for your resolution and size.
The procedure is as follows:
Once you have your vessel's nose pointing approximately on the target (works within a 12 degree cone), press the target key (default Left Ctrl+Alt+Enter).
Your target gets marked on screen with a red indicator, showing missile count on the left and distance to target on the right. If more than one target is within the cone, the nearest one gets marked.
Fire your missile with the launch key (Left Ctrl+Alt+Space) while a target is marked. The missile will immediately accelerate towards the target. You have 3 missiles on board. Target mark keeps active, but can be lost during missile pursuit. You can not fire missiles while landed, but your missile slots will be refilled on the ground.
If the target manages to out-maneuver the missile (12 degree seeker cone), the missile keeps on flying until another vessel comes into the cone. This will then be used as target.
If the missile hits the target, the ground or remains in flight 10 seconds after MECO, it will detonate. Both missile and target will disappear in a puffy smoke trail :rofl:.
Version 0.7.4 has been tagged and pushed to BitBucket here. This version fixes some bugs with STUN analysis and missile targeting.
Changes since 0.7.3:
OMPClient: refactored host sender to take parent attachments into account
This patch partially implements attachment support. If a vessel is attached as
child to a parent vessel and both are session objects, the client with the child
will send relative coordinates w.r.t. the parent vessel, thus creating a more
rigid illusion on the remote clients.
OMPMissile: refactored missile to take kill list and attach to biggest target
OMPClient: refactored missile target display to follow beyond seeker cone
OMPMissile: fix explosion on remote creation
Orbiter won't delete the OMPDefault representation of the missile at the same
timestep as creating the actual representation. Therefore the missile code finds
a vessel at 0,0,0 offset and consequently detonates.
OMPMissile: fix loop exit on collision detection
OMPMissile: fix ground impact detection for remote representation
OMPMissile: use half of size parameter for collision detection and smoke
OMPClient: refine missile targeting mechanism with rotation feature
OMPClient: fix kill list work up to be finished in single time step
STUN: switching implementation to RFC5389 compliance
ManagedPart: added STUN field to client configuration, default: stun.sipgate.net
stunserver.org is not working anymore, despite RFC compliance switch
STUN: added more progress information via log entries
OMPMissile: refined targeting mechanism
Except for these changes, the missile toy works as before:
Version 0.8 has been tagged and pushed to BitBucket here. This version jump is dominated by the switch from NTP to PTP clock syncing.
Changes since 0.7.4:
OMPClient: using custom STUN option for fixed sender port
OMPClient: check and display minimum supported server version
OMPClient: sending version information on connect
OMPClient: applying thrusters via KA packets now
OMPClient: fixed state information to combine MJD with state - Previously, only the timestamping base clock provided information about the SI latency. This was always jittering due to natural clock jitters in the µs area. Now the SI is taken closely together with the MJD, providing better latency info for the RK4 propagator. Using this, the non-rotating earth hack is not necessary anymore.
OMPClient: simplified RK4 propagator
OMPClient: added "%PTPdiv" client command to set PTP divider setting
OMPClient: fixed bug in master setting command
OMPClient: set proper IP endpoint on PTP ping packet
OMPClient: fixed configuration XSD/XML
OMPClient: introduce CheckSNTPServer() to determine NTP or PTP mode usage
OMPClient: introduce PTP divider to use every other keep-alive packet - Using every keep-alive packet as PTP protocol trigger is over-kill and produces many collisions (i.e.: previous PTP delay request wasn't even done yet).
OMPClient: propagate PTP info to NTPClient
OMPClient: implemented PTP protocol to ping for time-stamps after keep-alives
OMPClient: drop vessel creating packets with latency greater than GC limit
OMPClient: fixed logging of vessel creating state information packet
OMPClient: disabled STUN button while loading .NET assemblies
Server: display client version information in shell and web
Host: receive and check host version information
User: don't re-add SI-deleted vessels again
User: implemented PTP ping answer
Host: implemented "list all users" command without "detailed" specification - This command will be used by user list GUI later on.
Configuration: added CustomSTUN option - The CustomSTUN option can be activated if a custom port is set. In contrast to the normal custom port operation - where the port is used as fixed receiver - the custom STUN port is used as fixed sender, with the receiver operating like with Standard settings. This option may help with exotic NAT configurations where certain port ranges are blocked from sending/receiving.
Configuration: made whole NTP section optional
Wrapper: added managed version comparator function
Structures: added parser and comparator to Version class
Resources: fixed multiple use of identifiers - This should fix things like connecting/disconnecting on selecting log level 2.
ManagedPart: fixed CTD with no NTP servers defined
ManagedPart: refactored properties to auto-properties
NTPClient: added cycle measurement for adjustment algorithm in PTP mode
NTPClient: fixed event toggling from "Pinged" to "Idle" for better status
NTPClient: fixed PTP offset calculation
NTPClient: refactored for applying external PTP samples
OMPMissile: reverted to old targeting mechanism, but with refined aerodynamics
STUN: implemented proper Ia test with alternate server for symmetrical detection
0.8 will also mark a compatibility break, because the protocol changed a bit due to the PTP and MJD changes. In order to make that more transparent to the user, I have enhanced the version checking facility. Now the clients will announce their versions to the server and also request the server's version. Both sides can then check if the version falls into the compatibility range. If it does not, the client will disconnect with an appropriate error message, and the server will send a version that even pre-0.8 clients will reject. ATM there is no hard disconnect from the server side on such mismatches, but that may change in the future.
Currently 0.8 is the minimum server version that clients will support, and vice versa 0.8 is also the minimum client version a server will accept.
As hinted on in the change log above, the non-rotating earth hack has been removed. With this version, I hope the jitter has been reduced to a minimum, even with 300m/s rotation speed at the equator while "standing still". I have also removed the automatic relative state-information mode in favor of the manual "master" mode. I.e., that on-orbit operations will - at first - not be as smooth as before, but much more precise when it comes to absolute position. If you want to dock to someone, you can set the dock target as master to activate the relative positioning mode for smooth final approaches.
That said, I have no clue if all this will eventually hold "on the internet", so let's see how it works out...
User: only send observation group info with offers taken into account
User: implemented locked local ID guarding
Map: unroll recursive call in database parsers (no more old clients, anyway)
Host: don't allow raw prompts
Host: made server offer and accept response format deterministic
Config: reverted earth rotation offset, too
Settings: using scheme defaults instead of explicit default code
Settings: added container flag to XML scheme
Documentation: added TODO list with outlining of hand-over protocol
0.8.1 servers will accept 0.8 clients and 0.8.1 clients can join 0.8 servers.
Be aware that this version also removes the rotation offset of earth, which was a legacy from the days of the non-rotating earth hack. So if you join old servers with your new client (and vice versa), changes are that you are in the wrong position due to that. This is no fundamental incompatibility in the code, though, therefore you can simply change your earth.cfg accordingly.
The hand-over protocol is mostly server-based, so a new client joining an old server is simply unable to issue the command. However, an old client joining a new server could accept a hand-over offer, which will result in the loss of the object. Similarly, an old client joining a new server offering objects will result in duplication of the object.
In 0.8.1, the state vector transmission based on MJD timestamps introduced in 0.8 was refined by means of a snapshotting mechanism. Instead of getting simulation object states asynchronously in the sending/receiving thread, the system now maintains a synchronized snapshot list, which will be used on transceiving. This should in theory make docking less jumpy, because the consistency of state info wrt. timing info is guaranteed.
In order to get persistence, aka "my vessels stays in orbit while I'm offline", I'm pursuing the following strategy towards 0.9:
Administrators could run so called "container" clients, running the OMPClient with a special flag set, so it will react slightly differently to server calls and provides no meaningful user interaction. A good candidate for such a container is orbiter_ng running with no graphics client. It will just be there to run the physics on objects it maintains.
When clients crash or log-off, the server hands-over the orphaned objects to one or more containers. This way, the object remains in the server's universe, but maintained by the container instead of the actual client.
When a client logs in again, the container hands-over the objects again, letting the client continue where he left off.
With multiple container clients, loss of one container should not result in a total loss of objects.
With the help of containers, the server can save/load object states, so a server crash or restart should not result in a total loss of objects.
This version comes with 3 flags you can use to alter the behavior of the OMPClient's startup process: "QuickLaunch", "QuickLeave" and "Container", all three of them Boolean. They are optional attributes of the root element in the OMPClient.xml configuration.
"QuickLeave" is true by default, reflecting the current behavior of leaving the server (i.e. deleting all objects). In early versions of the software, this was not the case. Instead, you've got a dialog giving you the choice of "just" logging-out (and keeping the objects) or leaving completely on shutting down. If you set "QuickLeave" to false, you are back to this behavior.
"QuickLaunch" is false by default. If set to true, as soon as the OMPClient module is loaded, a connection is established, the given user is logged-in and a scenario with an OMPDefault vessel right in the sun is loaded. From there you can use the scenario editor and add vessels as usual. "QuickLeave" is forced to true with this, so when you quit the simulation, the system leaves the server and exits Orbiter.
While these flags are nice-to-haves, they are probably useless to most users. However, they are stepping stones for the third flag: "Container". If this flag is set to true (false by default), both "QuickLaunch" and "QuickLeave" are forced, and the system will act as container client instead of a normal client. This flag is implemented, but besides joining the server as declarated container client, nothing else of the above mentioned strategy is implemented ATM. This is where the next versions will expand.
The foundation for the strategy - the hand-over protocol - has been implemented already, and goes like this:
the sending user issues "\offer <number> <client>" in the chat-window, with <number> being the global ID of the vessel he wants to offer to <client>, with <client> being the name of the receiving user. Similar to trackings and observations, "\offer" alone will list all running offers and "\offer off" will retract them.
the receiving user issues "\accept <number> <local>" in the chat-window, with <number> being the global ID of the vessel which was offered to him, and <local> being the local ID it wants to use. Unfortunately, this later ID is not automated right now, but easily calculated: just count the number of vessels you have currently and use that number. If it fails, add 10. The algorithm re-uses skipped numbers, anyway. Again, similar to trackings and observations, "\accept" alone will list all available acceptable offers.
once the receiving user accepted the transfer, the remote vessel on his side will be deleted, and a new local vessel with the name and real class of the hand-over object will be created. Afterwards the receiving user can control the vessel as usual.
the sending user's vessel will be deleted and replaced by the remote representation of it.
If it pans out, the same protocol will be used in the future to hand-over vessels from crashing/logging-off clients to containers and back again, just server-triggered.