UnrealScript library and basis for all Acedia Framework mods
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

170 lines
4.5 KiB

class AvariceTcpLink extends TcpLink
dependson(LoggerAPI);
var private Global _;
var private string linkName;
var private string linkHost;
var private int linkPort;
var private IpAddr remoteAddress;
var private int ttt;
var private bool didWorkLastTick;
var private array<byte> buffer;
var private Utf8Encoder encoder;
var private Utf8Decoder decoder;
var private LoggerAPI.Definition infoSuccess;
var private LoggerAPI.Definition fatalBadPort;
var private LoggerAPI.Definition fatalCannotBindPort;
var private LoggerAPI.Definition fatalCannotResolveHost;
var private LoggerAPI.Definition fatalCannotConnect;
public final function bool Connect(string name, string host, int port)
{
local InternetLink.IpAddr ip;
local int usedPort;
// Apparently `TcpLink` ignores default values for these variables,
// so we set them here
linkMode = MODE_Binary;
receiveMode = RMODE_Manual;
_ = class'Global'.static.GetInstance();
encoder = Utf8Encoder(_.memory.Allocate(class'Utf8Encoder'));
decoder = Utf8Decoder(_.memory.Allocate(class'Utf8Decoder'));
linkName = name;
linkHost = host;
linkPort = port;
if (port <= 0)
{
_.logger.Auto(fatalBadPort)
.ArgInt(port)
.Arg(_.text.FromString(linkName));
return false;
}
if (BindPort(, true) <= 0)
{
_.logger.Auto(fatalCannotBindPort)
.ArgInt(port)
.Arg(_.text.FromString(name));
return false;
}
StringToIpAddr(host, remoteAddress);
remoteAddress.port = port;
if (remoteAddress.addr == 0) {
Resolve(host);
}
else {
OpenAddress();
}
return true;
}
event Resolved(IpAddr resolvedAddress)
{
remoteAddress.addr = resolvedAddress.addr;
OpenAddress();
}
private final function bool OpenAddress()
{
if (!OpenNoSteam(remoteAddress)) {
_.logger.Auto(fatalCannotConnect).Arg(_.text.FromString(linkName));
}
_.logger.Auto(infoSuccess).Arg(_.text.FromString(linkName));
}
event ResolveFailed()
{
_.logger.Auto(fatalCannotResolveHost).Arg(_.text.FromString(linkHost));
// !Shut down!
}
event Tick(float delta)
{
local array<byte> toSend;
local AvariceMessage nextAMessage;
local MutableText nextMessage;
local int i, j, dataRead, totalRead, iter;
local byte data[255];
if (didWorkLastTick)
{
didWorkLastTick = false;
return;
}
if (!IsDataPending()) {
return;
}
while (true) {
dataRead = ReadBinary(255, data);
for (i = 0; i < dataRead; i += 1) {
ttt += 1;
decoder.PushByte(data[i]);
}
if (dataRead <= 0) {
break;
}
}
if (ttt >= 4095) {
toSend = encoder.Encode(_.text.FromString("FLUSH"));
data[0] = toSend[0];
data[1] = toSend[1];
data[2] = toSend[2];
data[3] = toSend[3];
data[4] = toSend[4];
data[5] = 0;
SendBinary(6, data);
}
if (dataRead > 0) {
didWorkLastTick = true;
}
// Obtain!
nextMessage = decoder.PopText();
while (nextMessage != none)
{
Log("SIZE:" @ nextMessage.GetLength() @ ttt);
StopWatch(false);
nextAMessage = _.avarice.MessageFromText(nextMessage);
nextMessage.FreeSelf();
nextMessage = nextAMessage.ToText();
toSend = encoder.Encode(nextMessage);
toSend[toSend.length] = 0;
j = 0;
for (i = 0; i < toSend.length; i += 1)
{
data[j] = toSend[i];
j += 1;
if (j >= 255) {
j = 0;
SendBinary(255, data);
}
}
if (j > 0) {
SendBinary(j, data);
}
nextMessage.FreeSelf();
nextMessage = decoder.PopText();
StopWatch(true);
}
}
event Opened()
{
//Log("[TestTcp] Accepted!");
LOG("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
}
event Closed()
{
//Log("[TestTcp] Closed!");
}
defaultproperties
{
infoSuccess = (l=LOG_Info,m="Successfully started Avarice link \"%1\"")
fatalBadPort = (l=LOG_Fatal,m="Bad port \"%1\" specified for Avarice link \"%2\"")
fatalCannotBindPort = (l=LOG_Fatal,m="Cannot bind port for Avarice link \"%1\"")
fatalCannotResolveHost = (l=LOG_Fatal,m="Cannot resolve host \"%1\" for Avarice link \"%2\"")
fatalCannotConnect = (l=LOG_Fatal,m="Connection for Avarice link \"%1\" was rejected")
}