Squash merge #1505 - set socketServer IP/port via Lua (resolves #1495)

This commit is contained in:
Maximilian Peters 2019-05-29 07:06:38 +02:00 committed by James Groom
parent 27a4062ea2
commit 80c0fe571b
8 changed files with 298 additions and 143 deletions

View File

@ -13,7 +13,7 @@
#region MemoryMappedFiles
void MmfSetFilename(string filename);
string MmfSetFilename();
string MmfGetFilename();
int MmfScreenshot();
int MmfWrite(string mmf_filename, string outputString);
string MmfRead(string mmf_filename, int expectedSize);

View File

@ -48,14 +48,41 @@ namespace BizHawk.Client.EmuHawk
{
GlobalWin.socketServer.SetTimeout(timeout);
}
public void SocketServerSetIp(string ip)
{
GlobalWin.socketServer.Ip = ip;
}
public void SetSocketServerPort(int port)
{
GlobalWin.socketServer.Port = port;
}
public string SocketServerGetIp()
{
return GlobalWin.socketServer.Ip;
}
public int SocketServerGetPort()
{
return GlobalWin.socketServer.Port;
}
public string SocketServerGetInfo()
{
return GlobalWin.socketServer.GetInfo();
}
// All MemoryMappedFile related methods
public void MmfSetFilename(string filename)
{
GlobalWin.memoryMappedFiles.SetFilename(filename);
GlobalWin.memoryMappedFiles.Filename = filename;
}
public string MmfSetFilename()
public string MmfGetFilename()
{
return GlobalWin.memoryMappedFiles.GetFilename();
return GlobalWin.memoryMappedFiles.Filename;
}
public int MmfScreenshot()
@ -67,10 +94,13 @@ namespace BizHawk.Client.EmuHawk
{
return GlobalWin.memoryMappedFiles.WriteToFile(mmf_filename, Encoding.ASCII.GetBytes(outputString));
}
public string MmfRead(string mmf_filename, int expectedSize)
{
return GlobalWin.memoryMappedFiles.ReadFromFile(mmf_filename, expectedSize).ToString();
}
// All HTTP related methods
public string HttpTest()
{
@ -103,19 +133,19 @@ namespace BizHawk.Client.EmuHawk
}
public void HttpSetPostUrl(string url)
{
GlobalWin.httpCommunication.SetPostUrl(url);
GlobalWin.httpCommunication.PostUrl = url;
}
public void HttpSetGetUrl(string url)
{
GlobalWin.httpCommunication.SetGetUrl(url);
GlobalWin.httpCommunication.GetUrl = url;
}
public string HttpGetPostUrl()
{
return GlobalWin.httpCommunication.GetPostUrl();
return GlobalWin.httpCommunication.PostUrl;
}
public string HttpGetGetUrl()
{
return GlobalWin.httpCommunication.GetGetUrl();
return GlobalWin.httpCommunication.GetUrl;
}
}
}

View File

@ -2,14 +2,15 @@
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Windows.Forms;
namespace BizHawk.Client.EmuHawk
{
class ArgParser
//parses command line arguments and adds the values to a class attribute
//default values are null for strings and false for boolean
//the last value will overwrite previously set values
//unrecognized parameters are simply ignored or in the worst case assumed to be a ROM name [cmdRom]
class ArgParser
//parses command line arguments and adds the values to a class attribute
//default values are null for strings and false for boolean
//the last value will overwrite previously set values
//unrecognized parameters are simply ignored or in the worst case assumed to be a ROM name [cmdRom]
{
public string cmdRom = null;
public string cmdLoadSlot = null;
@ -21,13 +22,13 @@ namespace BizHawk.Client.EmuHawk
public string cmdDumpName = null;
public HashSet<int> _currAviWriterFrameList;
public int _autoDumpLength;
public bool _autoCloseOnDump = false;
// chrome is never shown, even in windowed mode
public bool _autoCloseOnDump = false;
// chrome is never shown, even in windowed mode
public bool _chromeless = false;
public bool startFullscreen = false;
public string luaScript = null;
public bool luaConsole = false;
public int socket_port = 9999;
public int socket_port = 0;
public string socket_ip = null;
public string mmf_filename = null;
public string URL_get = null;
@ -35,15 +36,14 @@ namespace BizHawk.Client.EmuHawk
public bool? audiosync = null;
public void ParseArguments(string[] args)
{
for (int i = 0; i < args.Length; i++)
{
// For some reason sometimes visual studio will pass this to us on the commandline. it makes no sense.
{
// For some reason sometimes visual studio will pass this to us on the commandline. it makes no sense.
if (args[i] == ">")
{
i++;
var stdout = args[i];
var stdout = args[i];
Console.SetOut(new StreamWriter(stdout));
continue;
}
@ -78,9 +78,9 @@ namespace BizHawk.Client.EmuHawk
foreach (string item in items)
{
_currAviWriterFrameList.Add(int.Parse(item));
}
// automatically set dump length to maximum frame
}
// automatically set dump length to maximum frame
_autoDumpLength = _currAviWriterFrameList.OrderBy(x => x).Last();
}
else if (arg.StartsWith("--dump-name="))
@ -140,39 +140,55 @@ namespace BizHawk.Client.EmuHawk
{
cmdRom = args[i];
}
}
////initialize HTTP communication
}
//initialize HTTP communication
if (URL_get != null || URL_post != null)
{
GlobalWin.httpCommunication = new Communication.HttpCommunication();
if (URL_get != null)
{
GlobalWin.httpCommunication.initialized = true;
GlobalWin.httpCommunication.SetGetUrl(URL_get);
GlobalWin.httpCommunication.GetUrl = URL_get;
}
if (URL_post != null)
{
GlobalWin.httpCommunication.initialized = true;
GlobalWin.httpCommunication.SetPostUrl(URL_post);
GlobalWin.httpCommunication.PostUrl = URL_post;
}
}
//inititalize socket server
if (socket_ip != null && socket_port > -1)
{
GlobalWin.socketServer.initialized = true;
}
//inititalize socket server
if (socket_ip != null && socket_port > 0)
{
GlobalWin.socketServer = new Communication.SocketServer();
GlobalWin.socketServer.SetIp(socket_ip, socket_port);
}
else if (socket_ip != null)
else if (socket_ip == null ^ socket_port == 0)
{
GlobalWin.socketServer.initialized = true;
GlobalWin.socketServer.SetIp(socket_ip);
}
//initialize mapped memory files
throw new ArgParserException("Socket server needs both --socket_ip and --socket_port. Socket server was not started");
}
//initialize mapped memory files
if (mmf_filename != null)
{
GlobalWin.memoryMappedFiles.initialized = true;
GlobalWin.memoryMappedFiles.SetFilename(mmf_filename);
GlobalWin.memoryMappedFiles = new Communication.MemoryMappedFiles();
GlobalWin.memoryMappedFiles.Filename = mmf_filename;
}
}
public static string GetCmdConfigFile(string[] args)
{
return args.FirstOrDefault(arg => arg.StartsWith("--config=", StringComparison.InvariantCultureIgnoreCase))?.Substring(9);
}
}
class ArgParserException : Exception
{
public ArgParserException()
{
}
public ArgParserException(string message) : base(message)
{
}
}
}
}

View File

@ -12,7 +12,6 @@ using BizHawk.Emulation.Common;
using BizHawk.Client.Common;
using BizHawk.Emulation.Common.IEmulatorExtensions;
using System.Windows.Forms;
using System.IO;
namespace BizHawk.Client.EmuHawk
{
@ -23,16 +22,14 @@ namespace BizHawk.Client.EmuHawk
public class HttpCommunication
{
private static HttpClient client = new HttpClient();
private string PostUrl = "http://localhost:9876/post/";
private string GetUrl = "http://localhost:9876/index";
public bool initialized = false;
public string PostUrl { get; set; } = null;
public string GetUrl { get; set; } = null;
private ScreenShot screenShot = new ScreenShot();
public int timeout = 0;
public int default_timeout = 500;
public void SetTimeout(int _timeout)
{
//timeout = _timeout.TotalMilliseconds;
if (timeout == 0 && _timeout == 0)
{
timeout = default_timeout;
@ -41,32 +38,15 @@ namespace BizHawk.Client.EmuHawk
{
client.Timeout = new TimeSpan(0, 0, 0, _timeout / 1000, _timeout % 1000);
timeout = _timeout;
}
}
public void SetPostUrl(string url)
{
PostUrl = url;
}
public void SetGetUrl(string url)
{
GetUrl = url;
}
public string GetGetUrl()
{
return GetUrl;
}
public string GetPostUrl()
{
return PostUrl;
}
}
public async Task<string> Get(string url)
{
client.DefaultRequestHeaders.ConnectionClose = false;
HttpResponseMessage response = await client.GetAsync(url).ConfigureAwait(false);
if (response.IsSuccessStatusCode) {
if (response.IsSuccessStatusCode)
{
return await response.Content.ReadAsStringAsync();
}
else
@ -82,11 +62,9 @@ namespace BizHawk.Client.EmuHawk
try
{
response = await client.PostAsync(url, content).ConfigureAwait(false);
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
return e.ToString();
}
@ -161,19 +139,40 @@ namespace BizHawk.Client.EmuHawk
return Post(PostUrl, content).Result;
}
}
public class SocketServer
{
string ip = null;
public string Ip
{
get { return ip; }
set
{
ip = value;
ipAdd = System.Net.IPAddress.Parse(ip);
Connect();
}
}
public string ip = "192.168.178.21";
public int port = 9999;
public Decoder decoder = Encoding.UTF8.GetDecoder();
public Socket soc = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
public IPAddress ipAdd;
public IPEndPoint remoteEP;
public IVideoProvider currentVideoProvider = null;
int port = 0;
public int Port
{
get { return port; }
set
{
port = value;
Connect();
}
}
Decoder decoder = Encoding.UTF8.GetDecoder();
Socket soc = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPAddress ipAdd;
IPEndPoint remoteEP;
IVideoProvider currentVideoProvider = null;
public bool connected = false;
public bool initialized = false;
public int retries = 10;
public int Retries { get; set; } = 10;
public bool success = false; //indicates whether the last command was executed succesfully
public void Initialize(IVideoProvider _currentVideoProvider)
@ -181,8 +180,8 @@ namespace BizHawk.Client.EmuHawk
currentVideoProvider = _currentVideoProvider;
SetIp(ip, port);
initialized = true;
}
public void Connect()
{
if (!initialized)
@ -194,42 +193,40 @@ namespace BizHawk.Client.EmuHawk
soc.Connect(remoteEP);
connected = true;
soc.ReceiveTimeout = 5;
}
public void SetIp(string ip_)
{
ip = ip_;
ipAdd = System.Net.IPAddress.Parse(ip);
remoteEP = new IPEndPoint(ipAdd, port);
}
public void SetIp(string ip_, int port_)
{
ip = ip_;
port = port_;
ipAdd = System.Net.IPAddress.Parse(ip);
remoteEP = new IPEndPoint(ipAdd, port);
}
public string GetInfo()
{
return $"{ip}:{port}";
}
public void SetTimeout(int timeout)
{
soc.ReceiveTimeout = timeout;
}
public void SocketConnected()
{
bool part1 = soc.Poll(1000, SelectMode.SelectRead);
bool part2 = (soc.Available == 0);
if (part1 && part2)
connected = false;
else
connected = true;
connected = !(part1 && part2);
}
public int SendString(string SendString)
{
int sentBytes = SendBytes(Encoding.ASCII.GetBytes(SendString));
success = sentBytes > 0;
return sentBytes;
}
public int SendBytes(byte[] SendBytes)
{
int sentBytes = 0;
@ -248,6 +245,7 @@ namespace BizHawk.Client.EmuHawk
{
return SendScreenshot(0);
}
public string SendScreenshot(int waitingTime)
{
if (!connected)
@ -262,7 +260,7 @@ namespace BizHawk.Client.EmuHawk
byte[] bmpBytes = screenShot.ImageToByte(img);
int sentBytes = 0;
int tries = 0;
while (sentBytes <= 0 && tries < retries)
while (sentBytes <= 0 && tries < Retries)
{
try
{
@ -279,7 +277,7 @@ namespace BizHawk.Client.EmuHawk
Connect();
}
}
success = (tries < retries);
success = (tries < Retries);
}
}
String resp = "";
@ -294,7 +292,7 @@ namespace BizHawk.Client.EmuHawk
{
return resp;
}
resp = "";
resp = ReceiveMessage();
if (resp == "")
{
@ -302,6 +300,7 @@ namespace BizHawk.Client.EmuHawk
}
return resp;
}
public string ReceiveMessage()
{
if (!connected)
@ -318,14 +317,15 @@ namespace BizHawk.Client.EmuHawk
{
receivedLength = soc.Receive(receivedBytes, receivedBytes.Length, 0);
resp += Encoding.ASCII.GetString(receivedBytes);
} catch
}
catch
{
receivedLength = 0;
}
}
return resp;
}
public bool Successful()
{
return success;
@ -334,29 +334,19 @@ namespace BizHawk.Client.EmuHawk
public class MemoryMappedFiles
{
public string filename_main = "BizhawkTemp_main";
public string Filename { get; set; } = "BizhawkTemp_main";
public Dictionary<string, MemoryMappedFile> mmf_files = new Dictionary<string, MemoryMappedFile>();
public int index = 0;
public bool initialized = false;
public int main_size = 10 ^ 5;
ScreenShot screenShot = new ScreenShot();
public void SetFilename(string filename)
{
filename_main = filename;
}
public string GetFilename()
{
return filename_main;
}
public int ScreenShotToFile()
{
ScreenShot screenShot = new ScreenShot();
var bb = screenShot.MakeScreenShotImage();
var img = bb.ToSysdrawingBitmap();
byte[] bmpBytes = screenShot.ImageToByte(img);
return WriteToFile(@filename_main, bmpBytes);
return WriteToFile(@Filename, bmpBytes);
}
public int WriteToFile(string filename, byte[] outputBytes)
@ -384,7 +374,6 @@ namespace BizHawk.Client.EmuHawk
}
catch (Exception)
{
}
mmf_file = MemoryMappedFile.CreateOrOpen(filename, outputBytes.Length);
@ -417,6 +406,7 @@ namespace BizHawk.Client.EmuHawk
{
private IVideoProvider currentVideoProvider = null;
private ImageConverter converter = new ImageConverter();
public BitmapBuffer MakeScreenShotImage()
{
if (currentVideoProvider == null)
@ -425,14 +415,17 @@ namespace BizHawk.Client.EmuHawk
}
return GlobalWin.DisplayManager.RenderVideoProvider(currentVideoProvider);
}
public byte[] ImageToByte(Image img)
{
return (byte[])converter.ConvertTo(img, typeof(byte[]));
}
public string ImageToString(Image img)
{
return Convert.ToBase64String(ImageToByte(img));
}
public string GetScreenShotAsString()
{
BitmapBuffer bb = MakeScreenShotImage();
@ -440,6 +433,18 @@ namespace BizHawk.Client.EmuHawk
return Convert.ToBase64String(imgBytes);
}
}
class CommunicationSocketServerException : Exception
{
public CommunicationSocketServerException()
{
}
public CommunicationSocketServerException(string message) : base(message)
{
}
}
}
}

View File

@ -26,8 +26,8 @@ namespace BizHawk.Client.EmuHawk
public static GLManager GLManager;
public static int ExitCode;
public static Communication.HttpCommunication httpCommunication = new Communication.HttpCommunication();
public static Communication.SocketServer socketServer = new Communication.SocketServer();
public static Communication.MemoryMappedFiles memoryMappedFiles = new Communication.MemoryMappedFiles();
public static Communication.HttpCommunication httpCommunication = null;
public static Communication.SocketServer socketServer = null;
public static Communication.MemoryMappedFiles memoryMappedFiles = null;
}
}

View File

@ -155,8 +155,15 @@ namespace BizHawk.Client.EmuHawk
.ReadAllBytes();
}
};
argParser.ParseArguments(args);
try
{
argParser.ParseArguments(args);
}
catch (ArgParserException e)
{
MessageBox.Show(e.Message);
}
Database.LoadDatabase(Path.Combine(PathManager.GetExeDirectoryAbsolute(), "gamedb", "gamedb.txt"));
@ -1398,6 +1405,7 @@ namespace BizHawk.Client.EmuHawk
private int _lastOpenRomFilter;
private ArgParser argParser = new ArgParser();
// Resources
private Bitmap _statusBarDiskLightOnImage;
private Bitmap _statusBarDiskLightOffImage;

View File

@ -113,9 +113,8 @@ namespace BizHawk.Client.EmuHawk
HawkFile.ArchiveHandlerFactory = new SevenZipSharpArchiveHandler();
var argParser = new ArgParser();
argParser.ParseArguments(args);
if (argParser.cmdConfigFile != null) PathManager.SetDefaultIniPath(argParser.cmdConfigFile);
string cmdConfigFile = ArgParser.GetCmdConfigFile(args);
if (cmdConfigFile != null) PathManager.SetDefaultIniPath(cmdConfigFile);
try
{

View File

@ -4,10 +4,6 @@ using NLua;
using BizHawk.Emulation.Common;
using BizHawk.Client.Common;
using System.Text;
using System.Collections.Generic;
using System.Net.Http;
using System.Windows.Forms;
namespace BizHawk.Client.EmuHawk
{
@ -37,70 +33,146 @@ namespace BizHawk.Client.EmuHawk
{
list.AppendLine(function.ToString());
}
return list.ToString();
}
[LuaMethod("socketServerScreenShot", "sends a screenshot to the Socket server")]
public string SocketServerScreenShot()
{
return GlobalWin.socketServer.SendScreenshot();
CheckSocketServer();
return GlobalWin.socketServer?.SendScreenshot();
}
[LuaMethod("socketServerScreenShotResponse", "sends a screenshot to the Socket server and retrieves the response")]
public string SocketServerScreenShotResponse()
{
return GlobalWin.socketServer.SendScreenshot(1000).ToString();
CheckSocketServer();
return GlobalWin.socketServer?.SendScreenshot(1000).ToString();
}
[LuaMethod("socketServerSend", "sends a string to the Socket server")]
public string SocketServerSend(string SendString)
public int SocketServerSend(string SendString)
{
return $"Sent : {GlobalWin.socketServer.SendString(SendString)} bytes";
if (!CheckSocketServer())
{
return -1;
}
return GlobalWin.socketServer.SendString(SendString);
}
[LuaMethod("socketServerResponse", "receives a message from the Socket server")]
public string SocketServerResponse()
{
return GlobalWin.socketServer.ReceiveMessage();
CheckSocketServer();
return GlobalWin.socketServer?.ReceiveMessage();
}
[LuaMethod("socketServerSuccessful", "returns the status of the last Socket server action")]
public bool SocketServerSuccessful()
{
if (!CheckSocketServer())
{
return false;
}
return GlobalWin.socketServer.Successful();
}
[LuaMethod("socketServerSetTimeout", "sets the timeout in milliseconds for receiving messages")]
public void SocketServerSetTimeout(int timeout)
{
GlobalWin.socketServer.SetTimeout(timeout);
CheckSocketServer();
GlobalWin.socketServer?.SetTimeout(timeout);
}
[LuaMethod("socketServerSetIp", "sets the IP address of the Lua socket server")]
public void SocketServerSetIp(string ip)
{
CheckSocketServer();
GlobalWin.socketServer.Ip = ip;
}
[LuaMethod("socketServerSetPort", "sets the port of the Lua socket server")]
public void SocketServerSetPort(int port)
{
CheckSocketServer();
GlobalWin.socketServer.Port = port;
}
[LuaMethod("socketServerGetIp", "returns the IP address of the Lua socket server")]
public string SocketServerGetIp()
{
return GlobalWin.socketServer?.Ip;
}
[LuaMethod("socketServerGetPort", "returns the port of the Lua socket server")]
public int? SocketServerGetPort()
{
return GlobalWin.socketServer?.Port;
}
[LuaMethod("socketServerGetInfo", "returns the IP and port of the Lua socket server")]
public string SocketServerGetInfo()
{
if (!CheckSocketServer())
{
return "";
}
return GlobalWin.socketServer.GetInfo();
}
private bool CheckSocketServer()
{
if (GlobalWin.socketServer == null)
{
Log("Socket server was not initialized, please initialize it via the command line");
return false;
}
return true;
}
// All MemoryMappedFile related methods
[LuaMethod("mmfSetFilename", "Sets the filename for the screenshots")]
public void MmfSetFilename(string filename)
{
GlobalWin.memoryMappedFiles.SetFilename(filename);
CheckMmf();
GlobalWin.memoryMappedFiles.Filename = filename;
}
[LuaMethod("mmfGetFilename", "Gets the filename for the screenshots")]
public string MmfSetFilename()
public string MmfGetFilename()
{
return GlobalWin.memoryMappedFiles.GetFilename();
CheckMmf();
return GlobalWin.memoryMappedFiles?.Filename;
}
[LuaMethod("mmfScreenshot", "Saves screenshot to memory mapped file")]
public int MmfScreenshot()
{
CheckMmf();
return GlobalWin.memoryMappedFiles.ScreenShotToFile();
}
[LuaMethod("mmfWrite", "Writes a string to a memory mapped file")]
public int MmfWrite(string mmf_filename, string outputString)
{
CheckMmf();
return GlobalWin.memoryMappedFiles.WriteToFile(mmf_filename, Encoding.ASCII.GetBytes(outputString));
}
[LuaMethod("mmfRead", "Reads a string from a memory mapped file")]
public string MmfRead(string mmf_filename, int expectedSize)
{
return GlobalWin.memoryMappedFiles.ReadFromFile(mmf_filename, expectedSize).ToString();
CheckMmf();
return GlobalWin.memoryMappedFiles?.ReadFromFile(mmf_filename, expectedSize).ToString();
}
private void CheckMmf()
{
if (GlobalWin.memoryMappedFiles == null)
{
Log("Memory mapped file was not initialized, please initialize it via the command line");
}
}
// All HTTP related methods
[LuaMethod("httpTest", "tests HTTP connections")]
public string HttpTest()
@ -111,51 +183,76 @@ namespace BizHawk.Client.EmuHawk
list.AppendLine("done testing");
return list.ToString();
}
[LuaMethod("httpTestGet", "tests the HTTP GET connection")]
public string HttpTestGet()
{
return GlobalWin.httpCommunication.TestGet();
CheckHttp();
return GlobalWin.httpCommunication?.TestGet();
}
[LuaMethod("httpGet", "makes a HTTP GET request")]
public string HttpGet(string url)
{
return GlobalWin.httpCommunication.ExecGet(url);
CheckHttp();
return GlobalWin.httpCommunication?.ExecGet(url);
}
[LuaMethod("httpPost", "makes a HTTP POST request")]
public string HttpPost(string url, string payload)
{
return GlobalWin.httpCommunication.ExecPost(url, payload);
CheckHttp();
return GlobalWin.httpCommunication?.ExecPost(url, payload);
}
[LuaMethod("httpPostScreenshot", "HTTP POST screenshot")]
public string HttpPostScreenshot()
{
return GlobalWin.httpCommunication.SendScreenshot();
CheckHttp();
return GlobalWin.httpCommunication?.SendScreenshot();
}
[LuaMethod("httpSetTimeout", "Sets HTTP timeout in milliseconds")]
public void HttpSetTimeout(int timeout)
{
GlobalWin.httpCommunication.SetTimeout(timeout);
CheckHttp();
GlobalWin.httpCommunication?.SetTimeout(timeout);
}
[LuaMethod("httpSetPostUrl", "Sets HTTP POST URL")]
public void HttpSetPostUrl(string url)
{
GlobalWin.httpCommunication.SetPostUrl(url);
CheckHttp();
GlobalWin.httpCommunication.PostUrl = url;
}
[LuaMethod("httpSetGetUrl", "Sets HTTP GET URL")]
public void HttpSetGetUrl(string url)
{
GlobalWin.httpCommunication.SetGetUrl(url);
CheckHttp();
GlobalWin.httpCommunication.GetUrl = url;
}
[LuaMethod("httpGetPostUrl", "Gets HTTP POST URL")]
public string HttpGetPostUrl()
{
return GlobalWin.httpCommunication.GetPostUrl();
CheckHttp();
return GlobalWin.httpCommunication?.PostUrl;
}
[LuaMethod("httpGetGetUrl", "Gets HTTP GET URL")]
public string HttpGetGetUrl()
{
return GlobalWin.httpCommunication.GetGetUrl();
CheckHttp();
return GlobalWin.httpCommunication?.GetUrl;
}
private void CheckHttp()
{
if (GlobalWin.httpCommunication == null)
{
Log("HTTP was not initialized, please initialize it via the command line");
}
}
}
}
}