AlliedModders

AlliedModders (https://forums.alliedmods.net/index.php)
-   Snippets and Tutorials (https://forums.alliedmods.net/forumdisplay.php?f=112)
-   -   [CSGO] Live game data (Open source) (https://forums.alliedmods.net/showthread.php?t=301056)

Lagoni 09-06-2017 15:50

[CSGO] Live game data (Open source)
 
So I made this simple example which reflects some of the ingame events such as positions, kills, smokes for the de_dust map. Feel free to further develop, or use this for inspiration for your own projects. If you have any questions feel free to contact me here or on github.

If anybody have some optimization ideérs, feel free to let me know! Since this, was one of the only ways I could see, how to reflect the ingame data and control it on a webpage the way you choose to. Hope some of you find some inspiration from this or can use part of it :gyar:

The project is achieved with Javascript, JQuery, Node.js, MySQL and sourcemod.

Github link for the project https://github.com/jonaslagoni/csgoLiveServer

Updating the position data for players
First lets break down the timer used to control the interval for players positions. Ill start off with the sourcemod plugin located here.


Code:

public Action Timer_player_positions(Handle timer){
//First I make sure that there are active players and not just an empty server. Since we dont want to update positions of no one.
        if(activePlayersCount != 0){
//Next I prepare the query for the database.
                StrCat(position_query, sizeof(position_query), "INSERT INTO positions (client_id, timestamp, pos_x, pos_y, pos_z) VALUES");
//This is used for determin if I already added a position to the query or not.
                new ran = false;
//Go through each of the players
                for(new i = 0; i < activePlayersCount; i++){
                        new clientId = GetArrayCell(activePlayers, i);
                        new client = GetClientOfUserId(clientId);
//Make sure they are in game and alive. Else we dont want to update their position
                        if(IsClientInGame(client) && IsPlayerAlive(client)){
                                if(ran){
                                        StrCat(position_query, sizeof(position_query), ",");
                                }
                                char player_walked_name[64];
                                GetClientName(client, player_walked_name, sizeof(player_walked_name));
                                new float:position[3];
                                GetEntPropVector(client, Prop_Send, "m_vecOrigin", position);
                                float pos_x = position[0];
                                float pos_y = position[1];
                                float pos_z = position[2];
                                int timestamp = GetTime();
//Format the string with the correct values for this client
                                Format(pp_query, sizeof(pp_query), " (%d, %d, %f, %f, %f)", clientId, timestamp, pos_x, pos_y, pos_z);
//Add the String to the query
                                StrCat(position_query, sizeof(position_query), pp_query);
                                ran = true;
                        }
                }
                if(ran){
//When done end the query and send it async*
                        StrCat(position_query, sizeof(position_query), ";");
                        csgoDatabase.Query(T_queryDone, position_query);
//Reset the query for next time
                        position_query = "";
                }
        }
        return Plugin_Continue;
}

When the position is updated from the game server the Node.js server takes over by checking each 100ms for new updates. The server code is located here. Ill walk you though it here:
Code:

//Using setInterval as a timer to get the data each 100ms
setInterval(function(){
  var query = "SELECT * FROM positions WHERE position_id > " + last_position_id;
  con.query(query, function(error, rows, fields){
    if(error) throw error;
//Check if the query returned some results
    if(rows.length > 0){
      console.log("found footstep");
//If there is only one new position only send 1 by socket to the clients
      if(rows.length == 1){
        io.emit('position', rows[0].pos_x, rows[0].pos_y, rows[0].pos_z, rows[0].client_id);
//Update the last retrieved position
        last_position_id = rows[0].position_id;
      }else{
//Since there are more then one position update send them all at once
        console.log("length = " + rows.length);
        var o = {};
        var key = '0';
        o[key] = [];
//Go though each position
        for(var i = 0; i < rows.length; i++){
          console.log("found footstep " + i + " of " + rows.length);
//Construct the data
          var data = {
            pos_x : rows[i].pos_x,
            pos_y : rows[i].pos_y,
            pos_z : rows[i].pos_z,
            client_id : rows[i].client_id
          };
//Push the data to the array
          o[key].push(data);
//Update the last retrieved position
          last_position_id = rows[i].position_id;
        }
//Send all the positions by socket
        io.emit('positions', o);
      }
    }
  });
}, 100);

When the Node.js server, located here, sends the message to the socket the client send the message to the map.js class located here.

Code:

//On a single position update
socket.on('position', function(pos_x, pos_y, pos_z, client_id){
    map.drawPlayer(pos_x, pos_y, pos_z, client_id);
});
//On multiple positions
socket.on('positions', function(data){
    map.drawPlayers(data);
});

Code:

function getPosX(pos_x){
//Correct location on the de_dust map for x-axis
  return ((Math.abs(pos_x+2850))/6.0)-10;
}
function getPosY(pos_y){
//Correct location on the de_dust map for y-axis
  return ((Math.abs(pos_y-4073))/6.0)-10;
}
  drawPlayer:function(pos_x, pos_y, pos_z, client_id){
//Get the correct positions of the user to reflect the correct position on the website
    var real_pos_x = getPosX(pos_x);
    var real_pos_y = getPosY(pos_y);
//Change the css to fit the correct position of the client
    $("#player".concat(client_id)).css("left", real_pos_x + "px");
    $("#player".concat(client_id)).css("top", real_pos_y + "px");
  },
  drawPlayers:function(data){
//Go through each of the positions in the array
    for(var i = 0; i < data['0'].length; i++){
//Get the correct positions of the user to reflect the correct position on the website
        var real_pos_x = getPosX(data['0'][i].pos_x);
        var real_pos_y = getPosY(data['0'][i].pos_y);
//Change the css to fit the correct position of the client
      $("#player".concat(data['0'][i].client_id)).css("left", real_pos_x + "px");
      $("#player".concat(data['0'][i].client_id)).css("top", real_pos_y + "px");
    }
  },


headline 09-06-2017 16:19

Re: [CSGO] Live game data (Open source)
 
Great job. This looks awesome.

_GamerX 09-06-2017 16:35

Re: [CSGO] Live game data (Open source)
 
Pretty much nice!

Lagoni 09-07-2017 07:31

Re: [CSGO] Live game data (Open source)
 
Thanks guys, appreciate it :up:
Since this is my first plugin for a CSGO server, I would love to get some feedback if you guys have any :)

-Updated the post with a little run through how updating the position on the players work :)

stephen473 09-07-2017 09:55

Re: [CSGO] Live game data (Open source)
 
Great! Thanks for share.

Peace-Maker 09-07-2017 10:42

Re: [CSGO] Live game data (Open source)
 
Good job! Having the webserver poll a database seems like a bad idea. You could think of creating a socket and directly pushing the data from the game server to your node server.

I've done similar before in CSS, but with the browser connecting directly to the gameserver via websockets instead of a seperate server somewhere. The demo is still up here. I have no clue about javascript, so this never got somewhere - yours looks way more promising. The code is attached here.

You could think of adding the view angle and health for a start!

Lagoni 09-07-2017 10:59

Re: [CSGO] Live game data (Open source)
 
Quote:

Originally Posted by Peace-Maker (Post 2547282)
Good job! Having the webserver poll a database seems like a bad idea. You could think of creating a socket and directly pushing the data from the game server to your node server.

I've done similar before in CSS, but with the browser connecting directly to the gameserver via websockets instead of a seperate server somewhere. The demo is still up here. I have no clue about javascript, so this never got somewhere - yours looks way more promising. The code is attached here.

You could think of adding the view angle and health for a start!

Nice, when I started, I was looking around for something like this, to remove the in between database, but didnt find anything, but this should do it! :up:

Peace-Maker 09-07-2017 11:19

Re: [CSGO] Live game data (Open source)
 
Quote:

Originally Posted by Lagoni (Post 2547285)
Nice, when I started, I was looking around for something like this, to remove the in between database, but didnt find anything, but this should do it! :up:

I wouldn't go the websocket route though. A proxy server which relays the information to all browsers is easier on the game server load and scales better.
You could even start recording the packets into a file and let players watch past matches in their browser that way :)

Lagoni 09-07-2017 11:48

Re: [CSGO] Live game data (Open source)
 
Relaying the information from the game server to the node.js server right?

What I need is the direct connection from the game server to my node.js server which sends it to the clients. And that could be achieved by using websockets.

Peace-Maker 09-07-2017 12:39

Re: [CSGO] Live game data (Open source)
 
Quote:

Originally Posted by Lagoni (Post 2547297)
Relaying the information from the game server to the node.js server right?

What I need is the direct connection from the game server to my node.js server which sends it to the clients. And that could be achieved by using websockets.

Yes, but you don't need the websocket protocol overhead if you don't connect to the browser directly. You should just use a regular socket.
https://forums.alliedmods.net/showthread.php?t=67640


All times are GMT -4. The time now is 18:52.

Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.