Connection to the server

In order to connect to the server, you need to:

  1. Download and install Lasertag Operator (LTO) app from Play Market.Qr code image

  2. If the app is already installed on your device, update it.

  3. Connect to a local network (LASERTAG, LASERTAG.NET, etc.) on your device. It will be displayed as a connection without internet.

    App item image
  4. Open the LTO application and from the “Lobby” menu go to the “Tools” menu.

  5. From the “Tools” menu, go to the “API” setting - it will be displayed at the top of the list.

    App item 2 imageApp item 3 image
  6. In the “API” menu, activate Automatic Start and Logging by sliding the switches, then click on the “Start server” button.

    App item 4 imageApp item 5 image
  7. Return to the “Lobby” menu and make sure the server is connected (icon Green arrow is green). If the icon Red arrow is red, restart the server in the API menu.

    App item 6 image
  8. If necessary, apply settings and connect the kits into the game.

LTO Api

Socket settings

LTO Api uses WebSocket to exchange data between the client and the server.

Attention

Do not use Windows hot-spot to connect between the client and server, as it may block broadcast messages.
The functionality is intended for work in a local network: Client < -- > Router < -- > Server.

Server URL

ws://< server ip address >:8080/lto

Instead of < server ip address > insert the IP address of the server (the device on which the Lasertag operator application is running).

Server auto discovery

To receive the IP address of a server, you can use server autodetection by sending a broadcast message.
Parameters for server autodetection:
Request tag - 0xc94222115fc942d3 (apply reverse to Request);
Response tag - 0xade7e97f3f51477b (apply reverse to Response);
Port – 4000.

After receiving a response from the server, subtract the first 8 bytes and compare them to the Response tag. After that you can get the IP address of the server and open the socket for operation.

Example of auto discovery server kotlin code:

copy icon
val REQUEST_TAG =
ByteBuffer.allocate(8).putLong(Long.reverseBytes(0xC94222115FC942D3u.toLong())).array()

val RESPONSE_TAG =
ByteBuffer.allocate(8).putLong(Long.reverseBytes(0xADE7E97F3F51477Bu.toLong())).array()

val PORT = 4000
val BROADCAST_ADDR ="255.255.255.255"
// socket sending to the server
val socket = DatagramSocket()
socket.broadcast = true
val sendPacket = DatagramPacket(REQUEST_TAG, sendData.size, 
InetAddress.getByName(BROADCAST_ADDR), PORT)
socket.send(sendPacket)
// reply from the server and get ip address
val recvData = ByteArray(128)
val recvPacket = DatagramPacket(recvData, recvData.size)
socket.receive(recvPacket)
val responceTag = responseData.sliceArray(0 until 8)
if (responceTag.contentEquals(RESPONSE_TAG))
val serverIp = recvPacket.address.hostAddress

Example of auto discovery server js code:

copy icon
const dgram = require('dgram');
      const socket = dgram.createSocket('udp4');
      
      const BROADCAST_ADDR = '255.255.255.255';
      const PORT = 4000;
      
      const REQUEST_TAG = new Uint8Array([0xC9, 0x42, 0x22, 0x11, 0x5F, 0xC9, 0x42, 0xD3]).reverse();
      const RESPONSE_TAG = new Uint8Array([0xAD, 0xE7, 0xE9, 0x7F, 0x3F, 0x51, 0x47, 0x7B]).reverse();
      
      async function sendBroadcast() {
        return new Promise((resolve, reject) => {
          socket.bind(() => {
            socket.setBroadcast(true);
      
            socket.send(REQUEST_TAG, 0, REQUEST_TAG.length, PORT, BROADCAST_ADDR, (err) => {
              if (err) {
                reject('Error sending broadcast message: ' + err);
              } else {
                console.log('Broadcast message sent');
              }
            });
 // Listen for responses
socket.on('message', (msg, rinfo) => {
              const response = msg.subarray(0, RESPONSE_TAG.length);
              if (response.equals(RESPONSE_TAG)) {
                const ws = new WebSocket(`ws://${response}:8080/lto`);
      
 // Add work with socket
        }
            });
          });
        });
      }

Protocol message structure

Protocol message headers
copy icon

  content-version : 1.0.0 
  message-format : message_type:{payload}
  message-type : string 
  payload-type : json
                
First type of message with payload
copy icon

  Structure:
  message_type:{payload}
  
  Example:
  StartGameType:{
  "game Time": 1730308650362
  }
  
  Explanation:
  message_type - StartGameType
  payload - {
  "gameTime": 1730308650362
  }
                
Second type of message without payload
copy icon

  Structure:
  message_type
  
  Example:
  PauseGameType
  
  Explanation:
  message_type - PauseGameType
                

The message consists of two parts: message_type and payload.
If the messages do not contain payload, only the message_type needs to be sent.
A list of all possible message_type is presented in the table below.

Server / client messages

Server to Client Messages

Message infoMessage typePayloadMessage example
Game start event. When the game starts, the round time is transmitted. Сonditions: Subscribtion to message on SubscribeOnGameEventsStartGame{ “gameTime”: 1800 }StartGame:{ “gameTime”: 1800 }
Game pause event. Сonditions: Subscribtion to message on SubscribeOnGameEventsPauseGamePauseGame
The event of canceling the pause of the game. Сonditions: Subscribtion to message on SubscribeOnGameEventsUnPauseGameUnPauseGame
End Game Event. Сonditions: Subscribtion to message on SubscribeOnGameEventsEndGameEndGame
The event of a player being wounded by another player. Сonditions: Subscribtion to message on SubscribeOnGameEventsPlayerHitPlayer{ “shooterId”: 1, “targetId”: 2, “time”: 1730114679815 } PlayerHitPlayer:{ “shooterId”: 1, “targetId”: 2, “time”: 1730114679815 }
The event of a player being killed by another player. Сonditions: Subscribtion to message on SubscribeOnGameEventsPlayerKillPlayer{ “shooterId”: 1, “targetId”: 2, “time”: 1730114680817 }PlayerKillPlayer:{ “shooterId”: 1, “targetId”: 2, “time”: 1730114680817 }
SMART DB capture event in Capture by Shots mode. Conditions: Subscribtion to message on SubscribeOnGameEventsDbSmartCaptureShots{ “deviceID”: 1 }DbSmartCaptureShots:{ “deviceID”: 1 }
SMART DB capture event in Capture by Time mode. Conditions: Subscribtion to message on SubscribeOnGameEventsDbSmartCaptureTime{ “deviceID”: 1 }DbSmartCaptureTime:{ “deviceID”: 1 }
SMART DB capture event in Tug of War mode. Conditions: Subscribtion to message on SubscribeOnGameEventsDbSmartCaptureTugOfWar{ “deviceID”: 1 }DbSmartCaptureTugOfWar:{ “deviceID”: 1 }
SMART DB capture event in “Triple Capture” mode. Conditions: Subscribtion to message on SubscribeOnGameEventsDbSmartCaptureThreePerson{ “deviceID”: 1 }DbSmartCaptureThreePerson:{ “deviceID”: 1 }
SMART DB capture event in “Flag Raising” mode. Conditions: Subscribtion to message on SubscribeOnGameEventsDbSmartCaptureFlag{ “deviceID”: 1 }DbSmartCaptureFlag:{ “deviceID”: 1 }
Multistation capture event in Control Point mode. Conditions: Subscribtion to message on SubscribeOnGameEventsMSCaptureControlPoint{ “deviceID”: 1 }MSCaptureControlPoint:{ “deviceID”: 1 }
Multistation capture event in Base mode. Conditions: Subscribtion to message on SubscribeOnGameEventsMSCaptureBase{ “deviceID”: 1 }MSCaptureBase:{ “deviceID”: 1 }
Multistation event “Bomb exploded” in “Bomb” mode. Conditions: Subscribtion to message on SubscribeOnGameEventsMSBombExplode{ “deviceID”: 1 }MSBombExplode:{ “deviceID”: 1 }
Multistation event “Bomb is planted” in “Bomb” mode. Conditions: Subscribtion to message on SubscribeOnGameEventsMSBombMine{ “deviceID”: 1 }MSBombMine:{ “deviceID”: 1 }
Multistation event “Bomb is demined” in the “Bomb” mode. Conditions: Subscribtion to message on SubscribeOnGameEventsMSBombDemine{ “deviceID”: 1 }MSBombDemine:{ “deviceID”: 1 }
SIRIUS station capture event in the “Base” mode. Conditions: Subscribtion to message on SubscribeOnGameEventsSiriusCaptureBase{ “deviceID”: 1 }SiriusCaptureBase:{ “deviceID”: 1 }
SUPERNOVA bomb event “Bomb Activation”. Conditions: Subscribtion to message on SubscribeOnGameEventsSupernovaActivation{ “deviceID”: 1 }SupernovaActivation:{ “deviceID”: 1 }
SUPERNOVA Bomb Event “Bomb is Activated”. Conditions: Subscribtion to message on SubscribeOnGameEventsSupernovaActivated{ “deviceID”: 1 }SupernovaActivated:{ “deviceID”: 1 }
SUPERNOVA bomb event “Bomb activation interrupted”. Conditions: Subscribtion to message on SubscribeOnGameEventsSupernovaActivationBreak{ “deviceID”: 1 }SupernovaActivationBreak:{ “deviceID”: 1 }
SUPERNOVA bomb event “Bomb Deactivation”. Conditions: Subscribtion to message on SubscribeOnGameEventsSupernovaDeactivation{ “deviceID”: 1 }SupernovaDeactivation:{ “deviceID”: 1 }
SUPERNOVA Bomb event “Bomb is deactivated”. Conditions: Subscribtion to message on SubscribeOnGameEventsSupernovaDeactivated{ “deviceID”: 1 }SupernovaDeactivated:{ “deviceID”: 1 }
SUPERNOVA bomb event “Deactivation interrupted”. Conditions: Subscribtion to message on SubscribeOnGameEventsSupernovaDeactivationBreak{ “deviceID”: 1 }SupernovaDeactivationBreak:{ “deviceID”: 1 }
SUPERNOVA Bomb Event “Bomb detonated.” Conditions: Subscribtion to message on SubscribeOnGameEventsSupernovaExplode{ “deviceID”: 1 }SupernovaExplode:{ “deviceID”: 1 }
SUPERNOVA Bomb event “Bomb is demined”. Conditions: Subscribtion to message on SubscribeOnGameEventsSupernovaDemine{ “deviceID”: 1 }SupernovaDemine:{ “deviceID”: 1 }
SUPERNOVA Bomb Event “The bomb has been placed on the platform.” Conditions: Subscribtion to message on SubscribeOnGameEventsSupernovaInstalledOnPlatform{ “deviceID”: 1 }SupernovaInstalledOnPlatform:{ “deviceID”: 1 }
SUPERNOVA Bomb Event “The bomb has been removed from the platform.” Conditions: Subscribtion to message on SubscribeOnGameEventsSupernovaDeInstalledOnPlatform{ “deviceID”: 1 }SupernovaDeInstalledOnPlatform:{ “deviceID”: 1 }
SUPERNOVA Bomb event “Cheats were detected while using the bomb”. Conditions: Subscribtion to message on SubscribeOnGameEventsSupernovaEventCheatHasBeenDetected{ “deviceID”: 1 }SupernovaEventCheatHasBeenDetected:{ “deviceID”: 1 }
Player statistics. Conditions: Subscribtion to message on SubscribeOnGameEventsPlayerState{ “playerId”: 0, “serialNumber”: 0, “shots”: 0, “hits”: 0, “kills”: 0, “hitsReceived”: 0, “accuracy”: 0.0, “points”: 0 }PlayerState:{ “playerId”: 0, “serialNumber”: 0, “shots”: 0, “hits”: 0, “kills”: 0, “hitsReceived”: 0, “accuracy”: 0.0, “points”: 0 }
Players statistics. Сonditions: Subscribtion to message on SubscribeOnGameEvents Sent in response to a request from a customer GetAllPlayerStatePlayersState{ “players”: [ { “playerId”: 0, “serialNumber”: 0, “shots”: 0, “hits”: 0, “kills”: 0, “hitsReceived”: 0, “accuracy”: 0.0, “points”: 0 }, { “playerId”: 0, “serialNumber”: 0, “shots”: 0, “hits”: 0, “kills”: 0, “hitsReceived”: 0, “accuracy”: 0.0, “points”: 0 } ] }PlayersState:{ “players”: [ { “playerId”: 0, “serialNumber”: 0, “shots”: 0, “hits”: 0, “kills”: 0, “hitsReceived”: 0, “accuracy”: 0.0, “points”: 0 }, { “playerId”: 0, “serialNumber”: 0, “shots”: 0, “hits”: 0, “kills”: 0, “hitsReceived”: 0, “accuracy”: 0.0, “points”: 0 } ] }

Client to Server Messages

Message infoMessage typePayloadMessage example
Subscriptions to receive game events. Transmits a list of events that will notify the client when they occur.SubscribeOnGameEvents{ "events":[ "StartGame", "EndGame", "PauseGame", "PlayerHitPlayer", "PlayerKillPlayer" ] } SubscribeOnGameEvents:{ "events":[ "StartGame", "EndGame", "PauseGame", "PlayerHitPlayer", "PlayerKillPlayer" ] }
Subscription to player status changesSubscribeOnPlayerStateChange{“subscribe”:true}SubscribeOnPlayerStateChange:{ “subscribe”:true }
Getting the status of all playersGetAllPlayerStateGetAllPlayerState