| 1 | using System;
|
|---|
| 2 | using System.Collections.Generic;
|
|---|
| 3 | using System.Runtime.InteropServices;
|
|---|
| 4 |
|
|---|
| 5 | namespace Loader
|
|---|
| 6 | {
|
|---|
| 7 | unsafe static class Program
|
|---|
| 8 | {
|
|---|
| 9 | delegate void CallPlayerHandler(int command, int player, int* data);
|
|---|
| 10 |
|
|---|
| 11 | [DllImport("cevo.dll", CallingConvention = CallingConvention.StdCall)]
|
|---|
| 12 | static extern void Run(IntPtr clientPtr);
|
|---|
| 13 |
|
|---|
| 14 | static CallPlayerHandler callPlayerHandler;
|
|---|
| 15 | static IntPtr clientPtr;
|
|---|
| 16 | static IntPtr serverPtr;
|
|---|
| 17 |
|
|---|
| 18 | static AIPlugin[] playerPlugin = new AIPlugin[Protocol.nPl];
|
|---|
| 19 | //static bool getReadyDone = false;
|
|---|
| 20 | static bool breakGameDone = false;
|
|---|
| 21 |
|
|---|
| 22 | static void CallPlayer(int command, int player, int* data)
|
|---|
| 23 | {
|
|---|
| 24 | if (command >= Protocol.cTurn)
|
|---|
| 25 | {
|
|---|
| 26 | if (player >= 0 && playerPlugin[player] != null)
|
|---|
| 27 | playerPlugin[player].Call(command, (IntPtr)data);
|
|---|
| 28 | }
|
|---|
| 29 | else
|
|---|
| 30 | {
|
|---|
| 31 | switch (command)
|
|---|
| 32 | {
|
|---|
| 33 | case Protocol.cInitModule:
|
|---|
| 34 | {
|
|---|
| 35 | serverPtr = ((IntPtr*)data)[0];
|
|---|
| 36 | ((int*)data)[2] = 4096; // reserve maximum possible
|
|---|
| 37 | break;
|
|---|
| 38 | }
|
|---|
| 39 |
|
|---|
| 40 | case Protocol.cNewGame:
|
|---|
| 41 | case Protocol.cLoadGame:
|
|---|
| 42 | { // possibly called multiple times per game because loader controls all .NET AIs
|
|---|
| 43 | // read string from data
|
|---|
| 44 | string assemblyPath = "";
|
|---|
| 45 | byte* read = (byte*)(data + 4 + 2 * Protocol.nPl);
|
|---|
| 46 | while (*read != 0)
|
|---|
| 47 | {
|
|---|
| 48 | assemblyPath += (char)*read;
|
|---|
| 49 | read++;
|
|---|
| 50 | }
|
|---|
| 51 |
|
|---|
| 52 | for (int playerX = 0; playerX < Protocol.nPl; playerX++)
|
|---|
| 53 | if (data[4 + Protocol.nPl + playerX] != 0)
|
|---|
| 54 | { // it's one of the players to use this assembly
|
|---|
| 55 | playerPlugin[playerX] = new AIPlugin(assemblyPath);
|
|---|
| 56 | playerPlugin[playerX].Initialize(playerX, serverPtr, (IntPtr)data, command == Protocol.cNewGame);
|
|---|
| 57 | }
|
|---|
| 58 |
|
|---|
| 59 | //getReadyDone = false;
|
|---|
| 60 | breakGameDone = false;
|
|---|
| 61 | break;
|
|---|
| 62 | }
|
|---|
| 63 |
|
|---|
| 64 | //case Protocol.cGetReady:
|
|---|
| 65 | // { // possibly called multiple times per game because loader controls all .NET AIs
|
|---|
| 66 | // if (!getReadyDone)
|
|---|
| 67 | // {
|
|---|
| 68 | // getReadyDone = true;
|
|---|
| 69 | // for (int playerX = 0; playerX < Protocol.nPl; playerX++)
|
|---|
| 70 | // {
|
|---|
| 71 | // if (playerPlugin[playerX] != null)
|
|---|
| 72 | // playerPlugin[playerX].Call(command, new IntPtr(data));
|
|---|
| 73 | // }
|
|---|
| 74 | // }
|
|---|
| 75 | // break;
|
|---|
| 76 | // }
|
|---|
| 77 |
|
|---|
| 78 | case Protocol.cBreakGame:
|
|---|
| 79 | { // possibly called multiple times per game because loader controls all .NET AIs
|
|---|
| 80 | if (!breakGameDone)
|
|---|
| 81 | {
|
|---|
| 82 | breakGameDone = true;
|
|---|
| 83 | Array.Clear(playerPlugin, 0, Protocol.nPl);
|
|---|
| 84 | }
|
|---|
| 85 | break;
|
|---|
| 86 | }
|
|---|
| 87 | }
|
|---|
| 88 | }
|
|---|
| 89 | }
|
|---|
| 90 |
|
|---|
| 91 | /// <summary>
|
|---|
| 92 | /// The main entry point for the application.
|
|---|
| 93 | /// </summary>
|
|---|
| 94 | [STAThread]
|
|---|
| 95 | static void Main()
|
|---|
| 96 | {
|
|---|
| 97 | callPlayerHandler = CallPlayer;
|
|---|
| 98 | clientPtr = Marshal.GetFunctionPointerForDelegate(callPlayerHandler);
|
|---|
| 99 | Run(clientPtr);
|
|---|
| 100 | }
|
|---|
| 101 | }
|
|---|
| 102 | }
|
|---|