Питон прекрасно умеет работать с сокетами, сделать рабочий пример не составит какого-то большого труда, заодно и людям поможете.
Или вы хотите использовать dll-библиотеку? Что вам ближе?
Чат со мной
Пример, надо отправить приватное сообщение человеку. На псевдокоде.
Константы:
CRLF - #13#10 (ASCII) 2 bytes
MCIAPI_CS_SendPrivateMessage = '0002'; (HEX)
MagicPacket - #23#6 (2 bytes)
cs_integration_api = '0077'; (4 bytes)
iFlag = 0 or 48 = '30' (2 bytes string)
Данные по сети отправляются в ASCII.
JSON объект для отправки приватного сообщения:
SendPrivateMessage JSON
{
"UserTo" : 15427,
"UserFrom" : 0,
"Msg" : "Hello",
"APIStype" : "joomla3x",
"ServerKey" : "iddqd"
}
Как отправить команду и получить ответ о том, что случилось?
try
1. Connect to IP/port
2. writeln "mc5.18"
3. readln (sc_hello)
4. writeln MagicPacket + cs_integration_api + iFlag + MCIAPI_CS_SendPrivateMessage + JSON
5. readln (JSON, server reply)
except
Ahtung!!! Network Error (SOCKET) number and description
end;
Чат со мной
Чат со мной
Чат со мной
Чат со мной
https://nsoft-s.com/mcserverhelp/index. ... ockets.htm
Чат со мной
writeln MagicPacket + cs_integration_api + iFlag + MCIAPI_CS_SendPrivateMessage + JSON
Я разделяю константы с помощью CLRF ? Т.е. MagicPacket<CRLF> cs_integration_api и т.д. ?
Пример на Indy, Delphi XE3. Без обработки ошибок и какой-либо логики, просто шаблон.
const
cs_integration_api = '0077';
MagicPacket = #23#6;
mcsignature = 'mc5.3';
MCIAPI_CS_SendPrivateMessage = '0002';
var
CSock: TidTCPClient;
sIn: string;
begin
CSock := TIdTCPClient.Create;
CSock.Host := sIP;
CSock.Port := iPort;
CSock.Connect;
CSock.Socket.WriteLnRFC(mcsignature); // функция WriteLnRFC сама добавляет в конец отправляемой строки два байта CRLF
sIn := CSock.Socket.ReadLn; // читаем входящую строку. Конец строки - CRLF, аналогично
CSock.Socket.WriteLnRFC(MagicPacket + cs_integration_api + IntToHex(iFlag, 2) + MCIAPI_CS_SendPrivateMessage + JSONobj.AsJSon);
sIn := CSock.Socket.ReadLn;
FreeAndNil(CSock);
end;
Чат со мной
Вот по идее всё правлиьно сделал - отправляется в сокет и тишина
import socket
import json
import struct
HOST = "se-ad01"
PORT = 2004
dict_obj = {
"UserTo": 4,
"UserFrom": 1,
"Msg": "Hello",
"hash": "",
"APIStype": "emailcheck",
"ServerKey": "1111"
}
n = json.dumps(dict_obj)
CRLF = r"\r\n"; # #13#10
CRLF = struct.pack("BB", 13, 10) # #13#10
MCIAPI_CS_SendPrivateMessage = struct.pack("l", 2) # l - signed long type. 4 bytes
MCIAPI_CS_IsUINOnline = struct.pack("l", 3)
MCIAPI_CS_SendChannelMessage = struct.pack("l", 4)
MCIAPI_CS_GetUINByNick = struct.pack("l", 5)
MCIAPI_CS_GetUINByEmail = struct.pack("l", 6)
MCIAPI_CS_IsUINExists = struct.pack("l", 7)
MCIAPI_CS_AddBBSMessage = struct.pack("l", 8)
MCIAPI_SC_SetChannelTopic = struct.pack("l", 9)
MCIAPI_CS_GetChannelNameByUID = struct.pack("l", 10)
MCIAPI_CS_IsChannelExists = struct.pack("l", 11)
MCIAPI_CS_GetUINByADLogin = struct.pack("l", 12)
MCIAPI_CS_GetInfoByUIN = struct.pack("l", 13)
MCIAPI_CS_GetServerInfo = struct.pack("l", 14)
MagicPacket = struct.pack("BB", 23, 6) # B - unsigned char. 1 byte
cs_integration_api = struct.pack("l", 77)
iFlag = struct.pack("h", 30) # h - signed short. 2 bytes
try:
try:
skt = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error as e:
print ("Error creating socket: %s" % e)
try:
skt.connect((HOST, PORT))
except socket.gaierror as e:
print("Address-related error connecting to server: %s" % e)
except socket.error as e:
print("Error connecting to socket: %s" % e)
try:
#skt.send(b'mc5.18')
#data = skt.recv(1024)
#print( bytes.decode(data))
skt.send(MagicPacket + cs_integration_api + iFlag + MCIAPI_CS_SendPrivateMessage + json.dumps(dict_obj))
data = skt.recv(1024)
print bytes.decode(data)
except socket.error as e:
print("Error connecting to socket: %s" % e)
finally:
skt.close()
Чат со мной
#skt.send(b'mc5.18')
#data = skt.recv(1024)
#print( bytes.decode(data))
Они должны быть раскомментированы, хотя бы первые две
Чат со мной
Чат со мной
import socket
import json
import struct
HOST = "se-ad01"
PORT = 2004
dict_obj = {
"UserTo": 4,
"UserFrom": 0,
"Msg": "Hello",
"hash": "",
"APIStype": "emailcheck",
"ServerKey": "1111"
}
n = json.dumps(dict_obj)
CRLF = r"\r\n"; # #13#10
CRLF = struct.pack("BB", 13, 10) # #13#10
MCIAPI_CS_SendPrivateMessage = struct.pack("l", 2) # l - signed long type. 4 bytes
MCIAPI_CS_IsUINOnline = struct.pack("l", 3)
MCIAPI_CS_SendChannelMessage = struct.pack("l", 4)
MCIAPI_CS_GetUINByNick = struct.pack("l", 5)
MCIAPI_CS_GetUINByEmail = struct.pack("l", 6)
MCIAPI_CS_IsUINExists = struct.pack("l", 7)
MCIAPI_CS_AddBBSMessage = struct.pack("l", 8)
MCIAPI_SC_SetChannelTopic = struct.pack("l", 9)
MCIAPI_CS_GetChannelNameByUID = struct.pack("l", 10)
MCIAPI_CS_IsChannelExists = struct.pack("l", 11)
MCIAPI_CS_GetUINByADLogin = struct.pack("l", 12)
MCIAPI_CS_GetInfoByUIN = struct.pack("l", 13)
MCIAPI_CS_GetServerInfo = struct.pack("l", 14)
MagicPacket = struct.pack("BB", 23, 6) # B - unsigned char. 1 byte
cs_integration_api = struct.pack("l", 77)
iFlag = struct.pack("h", 30) # h - signed short. 2 bytes
try:
try:
skt = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error as e:
print ("Error creating socket: %s" % e)
try:
skt.connect((HOST, PORT))
except socket.gaierror as e:
print("Address-related error connecting to server: %s" % e)
except socket.error as e:
print("Error connecting to socket: %s" % e)
try:
skt.send(b'mc5.18')
data = skt.recv(1024)
print( bytes.decode(data))
skt.send(MagicPacket + cs_integration_api + iFlag + MCIAPI_CS_SendPrivateMessage + json.dumps(dict_obj)+CRLF)
data = skt.recv(1024)
print bytes.decode(data)
except socket.error as e:
print("Error connecting to socket: %s" % e)
finally:
skt.close()
На что в ответ в сокет приходит
800000{"ServPass":false,"ServName":"","UpdatePacketVer":"","UTC":6,"RelDate":"23.03.2016","ProtocolVer":"2.17","PortNode":80,"PortFTP":20000,"ServerVer":"5.18.0","HTTPS":false,"Registered":"-","HelloMsg":"","UpdatePacketSize":44769884,"YourIP":"192.168.3.2","HWID":"340981260_4497_6-10-5-600000000","Free":true,"UpdateCRC32":4072895046,"ForceUpdate":true,"CurrentDT":"26.04.2016.20.15.38.021"}
А в логах сервера (см. вложение)
Вложения
Пожалуйста залогируйте и покажите текстовую строку, которую вы отправляете после получения sc_hello.
'\x17\x06M\x00\x00\x00\x1e\x00\x02\x00\x00\x00{"APIStype": "emailcheck", "hash": "", "ServerKey": "1111", "Msg": "Hello", "UserTo": 4, "UserFrom": 0}\r\n'
import socket
import json
import struct
HOST = "se-ad01"
PORT = 2004
dict_obj = {
"UserTo": 4,
"UserFrom": 0,
"Msg": "Hello",
"hash": "",
"APIStype": "customapi",
"ServerKey": "1111"
}
CRLF = r"\r\n"; # #13#10
CRLF = struct.pack("BB", 13, 10) # #13#10
# MCIAPI_CS_SendPrivateMessage = struct.pack("l", 2) # l - signed long type. 4 bytes
# MCIAPI_CS_IsUINOnline = struct.pack("l", 3)
# MCIAPI_CS_SendChannelMessage = struct.pack("l", 4)
# MCIAPI_CS_GetUINByNick = struct.pack("l", 5)
# MCIAPI_CS_GetUINByEmail = struct.pack("l", 6)
# MCIAPI_CS_IsUINExists = struct.pack("l", 7)
# MCIAPI_CS_AddBBSMessage = struct.pack("l", 8)
# MCIAPI_SC_SetChannelTopic = struct.pack("l", 9)
# MCIAPI_CS_GetChannelNameByUID = struct.pack("l", 10)
# MCIAPI_CS_IsChannelExists = struct.pack("l", 11)
# MCIAPI_CS_GetUINByADLogin = struct.pack("l", 12)
# MCIAPI_CS_GetInfoByUIN = struct.pack("l", 13)
# MCIAPI_CS_GetServerInfo = struct.pack("l", 14)
MCIAPI_CS_SendPrivateMessage = "0002"
MCIAPI_CS_IsUINOnline = "0003"
MCIAPI_CS_SendChannelMessage = "0004"
MCIAPI_CS_GetUINByNick = "0005"
MCIAPI_CS_GetUINByEmail = "0006"
MCIAPI_CS_IsUINExists = "0007"
MCIAPI_CS_AddBBSMessage = "0008"
MCIAPI_SC_SetChannelTopic = "0009"
MCIAPI_CS_GetChannelNameByUID = "0010"
MCIAPI_CS_IsChannelExists = "0011"
MCIAPI_CS_GetUINByADLogin = "0012"
MCIAPI_CS_GetInfoByUIN = "0013"
MCIAPI_CS_GetServerInfo = "0014"
MagicPacket = struct.pack("BB", 23, 6) # B - unsigned char. 1 byte
cs_integration_api = "0077"
# iFlag = struct.pack("h", 30) # h - signed short. 2 bytes
iFlag = "30"
try:
try:
skt = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error as e:
print ("Error creating socket: %s" % e)
try:
skt.connect((HOST, PORT))
except socket.gaierror as e:
print("Address-related error connecting to server: %s" % e)
except socket.error as e:
print("Error connecting to socket: %s" % e)
try:
skt.send(b'mc5.18\r\n')
data = skt.recv(1024)
print( bytes.decode(data))
skt.send(MagicPacket + cs_integration_api + iFlag + MCIAPI_CS_SendPrivateMessage + json.dumps(dict_obj)+CRLF)
data = skt.recv(1024)
print bytes.decode(data)
except socket.error as e:
print("Error connecting to socket: %s" % e)
finally:
skt.close()
MCIAPI_CS_SendPrivateMessage и iFlag - это у вас всё же строки...
Чат со мной
Другими словами: как в JSON сделать перевод строки, что бы клиент отработал это ?
Чат со мной
function ExecuteEx(FileName,Parameters,WorkFolder:string;RunType:integer):integer
RunType:
SW_HIDE Hides the window and activates another window.
SW_MAXIMIZE Maximizes the specified window.
SW_MINIMIZE Minimizes the specified window and activates the next top-level window in the Z order.
SW_RESTORE Activates and displays the window. If the window is minimized or maximized, Windows restores it to its original size and position. An application should specify this flag when restoring a minimized window.
SW_SHOW Activates the window and displays it in its current size and position.
SW_SHOWDEFAULT Sets the show state based on the SW_ flag specified in the STARTUPINFO structure passed to the CreateProcess function by the program that started the application.
SW_SHOWMAXIMIZED Activates the window and displays it as a maximized window.
SW_SHOWMINIMIZED Activates the window and displays it as a minimized window.
SW_SHOWMINNOACTIVE Displays the window as a minimized window. The active window remains active.
SW_SHOWNA Displays the window in its current state. The active window remains active.
SW_SHOWNOACTIVATE Displays a window in its most recent size and position. The active window remains active.
SW_SHOWNORMAL Activates and displays a window. If the window is minimized or maximized, Windows restores it to its original size and position. An application should specify this flag when displaying the window for the first time.
Использовать осторожно, запуск приложения из-под сервера — не очень хорошая идея, это должно быть легковесное приложение, которое быстро отработает.
Чат со мной
Чат со мной
Чтобы задать максимальное время выполнения скрипта, если он не укладывается в 5 секунд, воспользуйтесь функцией SetScriptTimeOut.
Чат со мной
Вам пример на C# нужен?
Чат со мной
Справка: https://nsoft-s.com/mcserverhelp/index. ... essage.htm
Обновить сервер: https://www.nsoft-s.com/files/mcserv.zip (установить поверху последней версии).
Пример на шарпе попробуем сделать на днях.
Чат со мной
using System;
using System.Net.Sockets;
using System.Net;
using System.IO;
using Newtonsoft.Json;
namespace Client
{
class PrivateMessage
{
public string UserTo { get; set; }
public string UserFrom { get; set; }
public string Msg { get; set; }
public string hash { get; set; }
public string APIStype { get; set; }
public string ServerKey { get; set; }
}
class AddBBSMessage
{
public string ServerKey { get; set; }
public string APIStyle { get; set; }
public string UserFrom { get; set; }
public string Expired { get; set; }
public string Sticky { get; set; }
public string Msg { get; set; }
}
class Program
{
static void Main(string[] args)
{
PrivateMessage PM = new PrivateMessage();
PM.UserTo = "2";
PM.UserFrom = "0";
PM.Msg = "lalala";
PM.hash = "";
PM.APIStype = "customapi";
PM.ServerKey = "U65aRYZfZM0zgrw6_MTi";
string json_send_message = JsonConvert.SerializeObject(PM);
AddBBSMessage add_bbs = new AddBBSMessage();
add_bbs.ServerKey = "U65aRYZfZM0zgrw6_MTi";
add_bbs.APIStyle = "customapi";
add_bbs.UserFrom = "1";
add_bbs.Expired = "10.09.2016.17.34.15";
add_bbs.Sticky = "true";
add_bbs.Msg = "html?";
string json_add_bbs = JsonConvert.SerializeObject(add_bbs);
string CRLF = "\u000D\u000A";
string MagicPacket = "\u0017\u0006";
string cs_integration_api = "0077";
string iFlag = "30";
string MCIAPI_CS_SendPrivateMessage = "0002";
string MCIAPI_CS_AddBBSMessage = "0008";
TcpClient client = new TcpClient();
client.Connect(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 2004));
StreamWriter sw = new StreamWriter(client.GetStream());
sw.AutoFlush = true;
string message = "mc5.18" + CRLF;
Console.WriteLine("Client : " + message);
sw.WriteLine(message);
StreamReader sr = new StreamReader(client.GetStream());
Console.WriteLine("Server : " + sr.ReadLine());
//message = aaa;
Console.WriteLine("Client : " + MagicPacket + cs_integration_api + iFlag + MCIAPI_CS_SendPrivateMessage + json_send_message + CRLF);
sw.WriteLine(MagicPacket + cs_integration_api + iFlag + MCIAPI_CS_AddBBSMessage + json_add_bbs + CRLF);
Console.WriteLine("Server : " + sr.ReadLine());
client.Close();
Console.ReadKey();
}
}
}
Чат со мной
Чат со мной
Хорошо, а перенос строки работает?? можно символами таблицу нарисовать.
<br> для переноса строки можно вставить.
Чат со мной
Чат со мной
string message = "mc5.20" + CRLF;
Ну и для всех, кто хочет воспользоваться примером для отправки сообщения, код должен быть таким:
Console.WriteLine("Client : " + MagicPacket + cs_integration_api + iFlag + MCIAPI_CS_SendPrivateMessage + json_send_message + CRLF);
sw.WriteLine(MagicPacket + cs_integration_api + iFlag + MCIAPI_CS_SendPrivateMessage + json_send_message + CRLF);
Просто в вашем примере, вы в консоль выводите информацию про команду отправки приватного сообщения, а отправляете серверу MCIAPI_CS_AddBBSMessage.
Чат со мной
using System;
using System.Net.Sockets;
using System.Net;
using System.IO;
using Newtonsoft.Json;
using System.Text;
namespace Client
{
class PrivateMessage
{
public string UserTo { get; set; }
public string UserFrom { get; set; }
public string Msg { get; set; }
public string hash { get; set; }
public string APIStype { get; set; }
public string ServerKey { get; set; }
}
class AddBBSMessage
{
public string ServerKey { get; set; }
public string APIStyle { get; set; }
public string UserFrom { get; set; }
public string Expired { get; set; }
public string Sticky { get; set; }
public string Msg { get; set; }
}
class Program
{
static void Main(string[] args)
{
PrivateMessage PM = new PrivateMessage();
PM.UserTo = "1";
PM.UserFrom = "0";
PM.Msg = "lalala";
PM.hash = "";
PM.APIStype = "customapi";
PM.ServerKey = "tRmbkBc6ZqHzuyk7dkEL";
string json_send_message = JsonConvert.SerializeObject(PM);
AddBBSMessage add_bbs = new AddBBSMessage();
add_bbs.ServerKey = "tRmbkBc6ZqHzuyk7dkEL";
add_bbs.APIStyle = "customapi";
add_bbs.UserFrom = "1";
add_bbs.Expired = "10.09.2016.17.34.15";
add_bbs.Sticky = "true";
add_bbs.Msg = @"текст ";
string json_add_bbs = JsonConvert.SerializeObject(add_bbs);
string CRLF = "\u000D\u000A";
string MagicPacket = "\u0017\u0006";
string cs_integration_api = "0077";
string iFlag = "30";
string MCIAPI_CS_SendPrivateMessage = "0002";
string MCIAPI_CS_AddBBSMessage = "0008";
TcpClient client = new TcpClient();
client.Connect(new IPEndPoint(IPAddress.Parse("192.168.1.10"), 2004));
StreamWriter sw = new StreamWriter(client.GetStream(),Encoding.GetEncoding(1251));
sw.AutoFlush = true;
string message = "mc5.20" + CRLF;
Console.WriteLine("Client : " + message);
sw.WriteLine(message);
StreamReader sr = new StreamReader(client.GetStream(),Encoding.GetEncoding(1251));
Console.WriteLine("Server : " + sr.ReadLine());
Console.WriteLine("Client : " + MagicPacket + cs_integration_api + iFlag + MCIAPI_CS_AddBBSMessage + json_add_bbs + CRLF);
sw.WriteLine(MagicPacket + cs_integration_api + iFlag + MCIAPI_CS_AddBBSMessage + json_add_bbs + CRLF);
Console.WriteLine("Server : " + sr.ReadLine());
client.Close();
Console.ReadKey();
}
}
}
Спасибо, чуть подправил, добавил кодировку 1251.
Вложения
Собственно, потому сервер в логе и писал ошибку, когда вы одним махом пытались пару команд отправить. Кодировка win1251 необязательна, кстати, JSON правильно обрабатывает юникодовые строки, делает из них ESC-последовательности.
Чат со мной
Спасибо за прототип Включим доработанный вариант в дистрибутив MyChat Server.
Чат со мной
Чат со мной