Jump to content
=KK=Des_

RCON и с чем его едят.

Recommended Posts

Сердечно приветсвую всех!

Давно не ковырялись с сервером и тут решили восстановить работу, но видимо после каких-то изменения и обновлений старые наработки перестали работать. На сервере настройки никакие не меняли.

Сейчас Rcon не хочет коннектиться снаружи по айпи и даже не коннектит по внутресетевому адресу "192.168.0.4". Коннект идет только по локалхосту (127.0.0.1). В чем может быть дело? Порты на роутере проброшены. Но даже если бы не было проброса портов почему не коннектит на 192,168,0,4?

Есть идеи?

Share this post


Link to post
Share on other sites

В пределах локалки, работает, только что проверил.

Share this post


Link to post
Share on other sites

 

 

Сейчас Rcon не хочет коннектиться

В СДС прописаны настройки ркон?

Share this post


Link to post
Share on other sites

 

В СДС прописаны настройки ркон?

Да конечно прописаны. Я же говорю что по адресу 127,0,0,1 коннектит и работает как надо. 

Share this post


Link to post
Share on other sites

Да конечно прописаны. Я же говорю что по адресу 127,0,0,1 коннектит и работает как надо. 

А сделайте плз скриншоты менеджера сдс и в этом менеджере вкладки ркон.

Без паролей.

Edited by -DED-ASF

Share this post


Link to post
Share on other sites

Сорри! затупил нереально!!!....Настроился. Кто-то в сдс айпи сменил!

Share this post


Link to post
Share on other sites

Еще по ркон. А отправку сообщений в чат прикрыли?


остыл всяких команд работает а вот чат что-то перестал(((

Share this post


Link to post
Share on other sites

Работает. В том числе и персональные сообщения

Share this post


Link to post
Share on other sites

Работает. В том числе и персональные сообщения

через румтайп 3 и 36-значный идентификатор пользователя

Share this post


Link to post
Share on other sites

Вдруг кому пригодится.

 

Код на питоне и C# для работы с ркон.

Python код немного не дописан, но обёртки команд по образцу дописать не сложно. Всё в итоге работает через метод __rcon_send_raw_command (формирование пакета подсмотрено в открытом коде Xedoc'а)

C# код писан в том году, работоспособность на тот момент была.
 
Python:

 

import socket
# import time


class RconCommunicator:
    """Communicate with IL-2 Battle of Stalingrad dedicated server
    through Server Remote Console - 'RCon'"""

    def __init__(self, tcp_ip, tcp_port, buffer_size=1024):
        self.TCP_IP = tcp_ip
        self.TCP_PORT = tcp_port
        self.BUFFER_SIZE = buffer_size
        self.SOCKET = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.SOCKET.settimeout(500)
        self.CONNECTED = False
        if self.TCP_IP and self.TCP_PORT:
            try:
                self.SOCKET.connect((self.TCP_IP, self.TCP_PORT))
                self.CONNECTED = True
            finally:
                self.AUTHED = False
                self.RESPONSE_LIST = []

    def __rcon_send_raw_command(self, command='mystatus'):
        """Sends command 'as is', may cause errors"""
        if hasattr(self, 'TCP_IP') == False \
                or hasattr(self, 'TCP_PORT') == False \
                or hasattr(self, 'BUFFER_SIZE') == False \
                or hasattr(self, 'SOCKET') == False:
            raise NameError("RconCommunicator NotInitialized")
        if type(command) is not str:
            raise NameError("type(command) is not str")

        if not self.CONNECTED:
            return None
        # формируем пакет
        cl = len(command) + 1
        pack_l = cl.to_bytes(2, byteorder='little')
        pack_m = command.encode(encoding='utf-8')
        pack_z = (0).to_bytes(1, byteorder='little')
        packet = pack_l + pack_m + pack_z

        # добавить проверку, установлено ли соединение
        # отправляем пакет
        try:
            self.SOCKET.send(packet)
        except:
            self.CONNECTED = False
            return None
        resp = self.SOCKET.recv(self.BUFFER_SIZE)
        self.RESPONSE_LIST.append((resp, command))
        return str(resp[2:-1], encoding="ascii")

    def reconnect(self):
        self.SOCKET.close()
        self.SOCKET = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.SOCKET.settimeout(500)
        self.CONNECTED = False
        try:
            self.SOCKET.connect((self.TCP_IP, self.TCP_PORT))
            self.CONNECTED = True
        finally:
            self.AUTHED = False

    def auth(self, user, password):
        """Authenticate communicator. Gives more permission if true"""
        if not self.CONNECTED:
            return False

        resp = self.__rcon_send_raw_command("auth {0} {1}".format(user, password))

        if len(resp):
            if resp[-1] == "1":
                self.AUTHED = True
                return True
            else:
                # self.AUTHED = False
                return False
        elif type(resp) is bytes and len(resp) == 0:
            self.AUTHED = True
            return True
        else:
            # self.AUTHED = False
            return False

    def server_status(self):
        if not self.CONNECTED:
            raise NameError("Not connected")
        resp = self.__rcon_send_raw_command("serverstatus")
        return resp

    def player_list(self):
        if not self.CONNECTED:
            raise NameError("Not connected")
        resp = self.__rcon_send_raw_command("getplayerlist")
        return resp

    def chatmsg(self, roomtype, id, message):
        if not self.CONNECTED:
            raise NameError("Not connected")
        resp = self.__rcon_send_raw_command("chatmsg {0} {1} {2}".format(roomtype, id, message))
        return resp

    def private_message(self, account_id, message):
        if not self.CONNECTED:
            raise NameError("Not connected")
        return self.chatmsg(3, account_id, message)

    def allies_message(self, message):
        if not self.CONNECTED:
            raise NameError("Not connected")
        return self.chatmsg(2, 1, message)

    def axis_message(self, message):
        if not self.CONNECTED:
            raise NameError("Not connected")
        return self.chatmsg(2, 2, message)

    def kick(self, name):
        if not self.CONNECTED:
            raise NameError("Not connected")
        resp = self.__rcon_send_raw_command("kick name {0}".format(name))
        return resp

    def server_input(self, server_input):
        if not self.CONNECTED:
            raise NameError("Not connected")
        resp = self.__rcon_send_raw_command("serverinput {0}".format(server_input))
        return resp

    pass  # class

 


 
C#

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Net;
using System.Net.Sockets;

namespace IL2RAconnector
{
    public class TcpConnector: IDisposable
    {
        TcpClient connection;
        NetworkStream stream;
        string host;
        ushort port;

        public TcpConnector(string host, ushort port)
        {
            // TODO: Complete member initialization
            this.host = host;
            this.port = port;
            connection = new TcpClient(host, (int)port);
            stream = connection.GetStream();
            
        }

        public string ExecuteCommand(string command)
        {
            Byte[] sendBytes = Encoding.UTF8.GetBytes(String.Concat(command));
            Byte[] length = BitConverter.GetBytes((ushort)(command.Length + 1));
            Byte[] zero = { 0 };
            Byte[] packet = length.Concat(sendBytes).Concat(zero).ToArray();

            stream.Write(packet, 0, packet.Length);

            packet = new Byte[connection.ReceiveBufferSize];

            Int32 bytes = stream.Read(packet, 0, packet.Length);

            UInt16 responseLength = BitConverter.ToUInt16(packet.Take(2).ToArray(), 0);

            string response = null;
            if (responseLength > 2)
                response = Encoding.UTF8.GetString(packet.Skip(2).Take((int)responseLength - 1).ToArray());
            //else
                //throw new Exception(BitConverter.ToString(packet));
            return response;
        }

        

        public int RecieveBufferSize { get { return connection.ReceiveBufferSize; } }



        public void Dispose()
        {
            stream.Close();
            connection.Close();
        }
    }
}
namespace IL2RAconnector
{
    public class RconCommunicator
    {
        private TcpConnector connection;
        
        public Stack<KeyValuePair<StatusCode, string>> History { get; private set; }
        public StatusCode lastCommandStatus { get; private set; }
        public string lastCommandResult { get; private set; }
        public List<Player> Players { get; private set; }

        public RconCommunicator(string host, ushort port)
        {
            connection = new TcpConnector(host, port);
            History = new Stack<KeyValuePair<StatusCode, string>>(Globals.HistorySize);
            Players = new List<Player>();
        }

        private void Execute(string cmd)
        {
            string response = connection.ExecuteCommand(cmd);
            string[] arr = { response, "" };

            if (response.Contains('&'))
            {
                arr = response.Split('&');
            }
            lastCommandStatus = (StatusCode)int.Parse(arr[0].Substring(7));
            lastCommandResult = Uri.UnescapeDataString(arr[1]); 

            History.Push(new KeyValuePair<StatusCode, string>(lastCommandStatus, lastCommandResult));
        }

        public string MyStatus()
        {
            //cmd: mystatus (no parameters)
            //response example: STATUS=1&authed=1
            string command = "mystatus";
            Execute(command);
            return lastCommandResult;
        }

        public string Auth(string user, string password)
        {
            //cmd: auth e-mail password
            //response example: STATUS=1
            string command = "auth " + user + " " + password;
            Execute(command);
            return lastCommandResult;
        }

        public string GetConsole()
        {
            //cmd: getconsole
            //response example: STATUS=1&console=
            string command = "getconsole";
            Execute(command);
            return lastCommandResult;
        }

        public List<Player> GetPlayerList()
        {
            //cmd: getplayerlist
            //response example: STATUS=1&playerList=
            //    playerList isnot defined when there is no players on the server,
            //    or a list of records with a columns:
            //playerList=cId,profileId,playerId,name,ingameStatus,nServerPing|
            //enum ingameStatus
            //{
            //    PS_SPECTATOR=0,
            //    PS_LOBBY_READY,
            //    PS______NONE___,
            //    PS_DOGFIGHT_READY,
            //    PS_CRAFTSITE_READY
            //}
            string command = "getplayerlist";
            Execute(command);

            string[] p = lastCommandResult.Split('|').Skip(1).ToArray();
            Players = new List<Player>(p.Count());

            foreach(var s in p)
            {
                string[] playerInfo = s.Split(',');
                Players.Add(new Player(int.Parse(playerInfo[0]), playerInfo[1], int.Parse(playerInfo[2]), playerInfo[3], playerInfo[4], playerInfo[5]));
            }

            return Players;
        }

        public string ServerStatus()
        {
            //cmd: serverstatus
            //response example: STATUS=1
            string command = "serverstatus";
            Execute(command);
            return lastCommandResult;
        }

        public string Kick(CmdValueType cmdValueType, string value)
        {
            //cmd: kick cid/name/playerid/profileid value
            //response example: STATUS=1
            string command = "kick ";
            switch (cmdValueType)
            {
                case CmdValueType.cid: 
                    command += "cid ";
                    break;
                case CmdValueType.name:
                    command += "name ";
                    break;
                case CmdValueType.playerid:
                    command += "playerid ";
                    break;
                case CmdValueType.profileid:
                    command += "profileid ";
                    break;
            }
            command += value;
            Execute(command);
            return lastCommandResult;
        }

        public string Ban(CmdValueType cmdValueType, string value)
        {
            //cmd: ban cid/name/playerid/profileid value
            //response example: STATUS=1
            string command = "ban ";
            switch (cmdValueType)
            {
                case CmdValueType.cid:
                    command += "cid ";
                    break;
                case CmdValueType.name:
                    command += "name ";
                    break;
                case CmdValueType.playerid:
                    command += "playerid ";
                    break;
                case CmdValueType.profileid:
                    command += "profileid ";
                    break;
            }
            command += value;
            Execute(command);
            return lastCommandResult;
        }

        public string BanUser(CmdValueType cmdValueType, string value)
        {
            //cmd: banuser cid/name/playerid/profileid value
            //response example: STATUS=1
            string command = "banuser ";
            switch (cmdValueType)
            {
                case CmdValueType.cid:
                    command += "cid ";
                    break;
                case CmdValueType.name:
                    command += "name ";
                    break;
                case CmdValueType.playerid:
                    command += "playerid ";
                    break;
                case CmdValueType.profileid:
                    command += "profileid ";
                    break;
            }
            command += value;
            Execute(command);
            return lastCommandResult;
        }

        public string UnbanAll()
        {
            //cmd: unbanall 
            //response example: STATUS=1
            string command = "unbanall";
            Execute(command);
            return lastCommandResult;
        }

        public string ServerInput(string translatorName)
        {
            //cmd: serverinput translator_name
            //response example: STATUS=1
            string command = "serverinput " + translatorName;
            Execute(command);
            return lastCommandResult;
        }

        public string SendStatNow()
        {
            //cmd: sendstatnow 
            //response example: STATUS=1
            string command = "sendstatnow";
            Execute(command);
            return lastCommandResult;
        }

        public string CutChatLog()
        {
            //cmd: cutchatlog
            //response example: STATUS=1
            string command = "cutchatlog";
            Execute(command);
            return lastCommandResult;
        }

        public string ChatMsg(RoomType roomType, string message, int recipientId)
        {
            //cmd: chatmsg roomtype id Message to send
            //response example: STATUS=1
            //chatmsg 0 -1 msg      (all)
            //chatmsg 1 cid msg     (coalition message, 0 - neutral, 1 - allies, 2 - axis)
            //chatmsg 2 cid msg     (country message, 0 - all)
            //chatmsg 3 cid msg     (private message, cid - client id from playerlist)
            

            string command;
            switch (roomType)
            {
                case RoomType.All:
                    command = string.Format("chatmsg 0 -1 {0}", message);
                    break;
                case RoomType.Coalition:
                    command = string.Format("chatmsg 1 {0} {1}", recipientId, message);
                    break;
                case RoomType.Country:
                    command = string.Format("chatmsg 2 {0} {1}", recipientId, message);
                    break;
                case RoomType.ClientId:
                    command = string.Format("chatmsg 3 {0} {1}", recipientId, message);
                    break;
                default: return string.Empty;
            }
            Execute(command);
            return lastCommandResult;
        }

        
    }
}

namespace IL2RAconnector
{
    public class Player
    {
        public int Cid { get; private set; }
        public string Name { get; private set; }
        public string ProfileId { get; private set; }
        public string PlayerId { get; private set; }
        public string IngameStatus { get; private set; }
        public int Ping { get; private set; }

        public Player(int cid, string ingameStatus, int ping, string unescapedName, string unescapedPlayerId, string unescapedProfileId)
        {
            Cid = cid;
            ProfileId = Uri.UnescapeDataString(unescapedProfileId);
            PlayerId = Uri.UnescapeDataString(unescapedPlayerId);
            IngameStatus = ingameStatus;
            Ping = ping;
            Name = Uri.UnescapeDataString(unescapedName);
        }
    }
}
 

 

 

  • Upvote 3

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...