Jump to content

Photo
- - - - -

MySQL and ArmA2


  • Please log in to reply
No replies to this topic
Thread Starter
rocket
rocket

    BI Developer

  • 648 posts

  • Joined: 11-June 2007

Posted 28 September 2011 - 12:34 #1

Since formally announcing the USEC Revolution system I've been inundated with requests for how to do this. Here's a really quick outline of how to do it, using JayArmA2Lib. More detail will be provided when the entire source is released.

The system is made up of the following:
  • ArmA2 Dedicated Server Install
  • JayArmA2Lib
  • MySQL 5.1
  • Custom Console App: "Mother"
  • C++ MySQL Connector

Mission Transactions

Inside the USEC Revolution system, "transactions" are created which are passed to Mother and processed. One option, would be to directly pass SQL but I preferred to leave the SQL out, for security reasons.

Transactions are sent in a string, and then broken into pieces to be processed by mother. Here is an example of it breaking apart the transactions:

/* Read from pipe	*/
std::string output = GetPipeString();
cout << "Received...";
cout << output << endl;

/* FINISHED PROCESSING TRANSACTION */
std::vector<std::string> transKey = TransactionDecode(output);
std::string trCode = transKey[1];
int trCodeInt = atoi(trCode.c_str());

This uses my "TransactionDecode" functions:
std::vector<std::string> TransactionDecode(std::string input)
{
	std::vector<std::string> transKey;
	boost::split(transKey, input, boost::is_any_of(":"));
	//transKey.pop_back(); //Remove garbage from the end
	return transKey;
}

This uses my "GetPipeString" function:
std::string GetPipeString()
{
	/*	
		READ FROM PIPE
		Example:	std::string output = GetPipeString();
	*/
	char	buf[BUFSIZE];			//buffer for receiving
	DWORD	dwBytesRead;
	std::stringstream	ss;//create a stringstream
	std::string		output;
	ReadFile (hPipe,buf, BUFSIZE, &dwBytesRead, NULL);
	ss << buf;//add number to the stream
	output = ss.str();
	output.erase(output.end() - 1);	//remove the garbage character
	return output;
}

Here is a sample transaction in the mission, generated by the SERVER (clients can generate requests to the server, who then passes them on) whenever the location of a vehicle needs to be updated:

_key = format["CHILD:302:1:%1:%2:%3:%4:%5:%6:%7:%8:%9:%10:",USEC_RegionID,_vehID,_locX,_locY,_locZ,_dir,0,0,USEC_LocID,USEC_LocType];
_result = [_key,false] spawn USEC_Fnc_MotherRequest;

The USEC_Fnc_MotherRequest is as follows:

Spoiler


Mother

The "core" of this system is called Mother. This is in reference to the "Mother" system in the Alien movies. Essentially, Mother creates a named pipe, which can be shared with JayArmA2Lib. Think of this as a dedicated telephone system between ArmA2 and a custom application.

Now, let me be clear. Named Pipes are a reasonably advanced concept, and to get MySQL working you are going to need to have an excellent knowledge of named pipes and a sound knowledge of C++, but it isn't impossible to achieve for a dedicated individual with some coding knowledge and, alot of patience, in a few weeks.

Here is a sample of the processing of a transaction. This transaction streams in buildings into ArmA2 on server restart, creating the persistent world:
Spoiler


The Mother-to-Mission "Handshake"

This is one of the hardest bits. Named pipes can be a bit trickey to syncronize.

Here is an example of a handshake mixed with JayArmA2Lib:
Spoiler


I'll expand this into a wiki article when time allows, in the meantime, any questions please post them below and I will do my best to answer.

Edited by Rocket, 28 September 2011 - 12:47.

"He will come to death. An image of the splendor of the kings of men in glory, undimmed before the breaking of the world."