Jump to content

Recommended Posts

Hello everybody,

 

I'm creating an extension to remote sqf function by socket.

 

For the moment I'm just trying to connect to the server, start the process by calling extension from arma and execute the client application.

 

But, I can't connect and when I look the log I have "Client connected" on every frame even without my client application.

 

Before, create the .dll I tried with a server application and there's no problem.


#include "stdafx.h"

#include <unordered_map> 
#include <thread> 
#include <mutex> 
#include <atomic> 

#pragma comment(lib,"Ws2_32.lib")
#include <WinSock2.h>
#include <iostream>
#include <string>
#include <fstream>

#include "Log.h"

const int MAX_CONNECTION = 20;
char PASSWORD[MAX_CONNECTION];
char IP[MAX_CONNECTION];
int PORT;
const int MESSAGE_SIZE = 256;

SOCKET connections[MAX_CONNECTION];
int connectionCounter = 0;

bool socketWorking = false;

using namespace std;
struct Data
{
	bool ready = false;
	string params = "";
	string result = "";
};

unordered_map<long int, Data> tickets;
mutex mtx;
atomic<bool> worker_working(false);
long int id = 0; // global ticket id 
long int cur_id = 0; // current ticket id

int clientHandlerThread(int index)
{
	char buffer[MESSAGE_SIZE];

	//password check

	writeInFile("connection", "Waiting for password");

	recv(connections[index], buffer, sizeof(buffer), NULL);

	if (strcmp(buffer, PASSWORD) != 0)
	{
		strcpy_s(buffer, "refused");
		send(connections[index], buffer, sizeof(buffer), NULL);
		connectionCounter--;
		return 0;
	}
	else
	{
		strcpy_s(buffer, "accepted");
		send(connections[index], buffer, sizeof(buffer), NULL);
	}


	while (strcmp(buffer, "exit") != 0)
	{
		recv(connections[index], buffer, sizeof(buffer), NULL);
		writeInFile("message", (char*)(std::string("Message: ") + std::string(buffer)).c_str());
	}

	connectionCounter--;
	return 0;
}


bool getConfig() {
	std::ifstream confFile("AventuraRCon//config.txt", std::ifstream::binary);
	if (confFile) {
		std::string line;
		//ip
		std::getline(confFile, line);
		strcpy_s(IP, (char*)line.c_str());
		writeInFile("config", (char*)(std::string("IP : ") + std::string(IP)).c_str());
		//port
		std::getline(confFile, line);
		PORT = atoi(line.c_str());
		writeInFile("config", (char*)(std::string("PORT : ") + line).c_str());
		//password
		std::getline(confFile, line);
		strcpy_s(PASSWORD, (char*)line.c_str());
		writeInFile("config", (char*)(std::string("PASSWORD : ") + std::string(PASSWORD)).c_str());
	}
	else
	{
		return false;
	}

	return true;
}

void socketWorker()
{

	if (!getConfig())
	{
		return ;
	}

	//winsock startup
	WSAData wsaData;
	WORD DllVersion = MAKEWORD(2, 1);
	if (WSAStartup(DllVersion, &wsaData) != 0)
	{
		return;
	}

	socketWorking = true;


	SOCKADDR_IN addr;
	int addrlen = sizeof(addr);
	addr.sin_addr.s_addr = inet_addr(IP);
	addr.sin_port = htons(PORT);
	addr.sin_family = AF_INET;

	SOCKET sListen = socket(AF_INET, SOCK_STREAM, NULL);
	bind(sListen, (SOCKADDR*)&addr, sizeof(addr));
	listen(sListen, SOMAXCONN);

	SOCKET newConnection;

	while (true) {

		if (connectionCounter < MAX_CONNECTION)
		{
			newConnection = accept(sListen, (SOCKADDR*)&addr, &addrlen);
			if (newConnection == 0)
			{
				writeInFile("debug", "Client can't connect");
				closesocket(newConnection);
				WSACleanup();
			}
			else
			{
				writeInFile("debug", "Client connected");
				connections[connectionCounter] = newConnection;
				CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)clientHandlerThread, (LPVOID)(connectionCounter), NULL, NULL);
				connectionCounter++;
			}
		}
		else
		{
			Sleep(10);
		}


	}

	return ;
}


extern "C" 
{ 
	__declspec (dllexport) void __stdcall RVExtension(char *output, int outputSize, const char *function); 
}

void worker() 
{
	//to-do later
} 

void __stdcall RVExtension(char *output, int outputSize, const char *function) 
{

	if (!strcmp(function, "Start"))
	{
		//start socketworker
		if (socketWorking)
		{
			strncpy_s(output, outputSize, "ALREADY WORKING", _TRUNCATE); 
			
		}
		else
		{
			CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)socketWorker, NULL, NULL, NULL);
			strncpy_s(output, outputSize, "DONE", _TRUNCATE); 
			
		}
		
	}
	else if (!strncmp(function, "C:", 2)) // searching for command
	{ 
		if (!tickets.empty()) 
		{ 
			mtx.lock(); 
			strncpy_s(output, outputSize, tickets[0].params.c_str(), _TRUNCATE); // result 
			mtx.unlock(); 
			return;
		} 
		strncpy_s(output, outputSize, "EMPTY", _TRUNCATE);
		
	} 
	else if (!strncmp(function, "R:", 2)) // sending result
	{ 
		mtx.lock(); 
		std::string tmp = function;
		tickets.at(0).result = (char*)tmp.substr(2, size_t(function) - 2).c_str();
		tickets.at(0).ready = true;
		mtx.unlock(); 
		strncpy_s(output, outputSize, "DONE", _TRUNCATE);
		
	} 
	else 
	{ 
		strncpy_s(output, outputSize, "INVALID COMMAND", _TRUNCATE);
		
	} 
}

To create it I use this tutorial:

 

http://killzonekid.com/arma-scripting-tutorials-how-to-make-arma-extension-part-4/

 

and, this one:

 

 

I've already did some .dll, but this time I really don't know where's the problem.

 

Any solution?

Share this post


Link to post
Share on other sites

I find the solution!

 

It's not a Arma3 problem, when you use WinSock2 with using namespace std; make sure to add :: before any socket function, or just don't use using namespace std ;)

Share this post


Link to post
Share on other sites

I find the solution!

 

It's not a Arma3 problem, when you use WinSock2 with using namespace std; make sure to add :: before any socket function, or just don't use using namespace std ;)

Did the intellisense in VS not tell you you are requesting resource in wrong namespace?

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now

×