Skip to content

Commit cc407bf

Browse files
Merge pull request #54 from MasterLaplace/53-feature-implement-unity-library
Implement unity library
2 parents c3755d0 + 7da7db0 commit cc407bf

File tree

20 files changed

+1477
-0
lines changed

20 files changed

+1477
-0
lines changed
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
using System;
2+
using System.Net;
3+
using System.Net.Sockets;
4+
using System.Collections.Generic;
5+
using UnityEngine;
6+
7+
using Flk_API = Flakkari4Unity.API;
8+
using CurrentProtocol = Flakkari4Unity.Protocol.V1;
9+
10+
public class NetworkClient : MonoBehaviour
11+
{
12+
private UdpClient udpClient;
13+
private IPEndPoint serverEndpoint;
14+
private readonly float keepAliveInterval = 3;
15+
private string serverIP;
16+
private int serverPort;
17+
private string gameName;
18+
private bool enable = false;
19+
20+
public bool Enable
21+
{
22+
get => enable;
23+
}
24+
25+
public void Create(string serverIP, int serverPort, string gameName)
26+
{
27+
this.serverIP = serverIP;
28+
this.serverPort = serverPort;
29+
this.gameName = gameName;
30+
enable = true;
31+
32+
udpClient = new UdpClient();
33+
serverEndpoint = new IPEndPoint(IPAddress.Parse(serverIP), serverPort);
34+
35+
udpClient.BeginReceive(OnReceive, null);
36+
37+
byte[] packet = Flk_API.APIClient.ReqConnect(gameName);
38+
udpClient.Send(packet, packet.Length, serverEndpoint);
39+
InvokeRepeating(nameof(ReqKeepAlive), keepAliveInterval, keepAliveInterval);
40+
}
41+
42+
internal void Send(byte[] packet)
43+
{
44+
if (udpClient != null)
45+
{
46+
udpClient.Send(packet, packet.Length, serverEndpoint);
47+
}
48+
else
49+
{
50+
Debug.LogError("UDP client is not initialized.");
51+
}
52+
}
53+
54+
private void ReqKeepAlive()
55+
{
56+
byte[] packet = Flk_API.APIClient.ReqKeepAlive();
57+
udpClient.Send(packet, packet.Length, serverEndpoint);
58+
}
59+
60+
private void OnReceive(IAsyncResult result)
61+
{
62+
if (!enable)
63+
return;
64+
65+
try
66+
{
67+
byte[] receivedData = udpClient.EndReceive(result, ref serverEndpoint);
68+
Flk_API.APIClient.Reply(receivedData, out List<CurrentProtocol.CommandId> commandId, out List<ulong> sequenceNumber, out List<byte[]> payload);
69+
70+
Flakkari4Unity.Synchronizer synchronizer = gameObject.GetComponent<Flakkari4Unity.Synchronizer>();
71+
72+
for (int i = 0; i < commandId.Count; i++)
73+
{
74+
switch (commandId[i])
75+
{
76+
case CurrentProtocol.CommandId.REP_CONNECT:
77+
Flk_API.APIClient.ResConnect(payload[i], ref synchronizer, out ulong entityId);
78+
79+
Player playerScript = synchronizer.GetEntity(entityId).GetComponent<Player>();
80+
playerScript.SetupCameraViewport(new Rect(0, 0, 1, 1));
81+
playerScript.SetupNetworkClient(this);
82+
break;
83+
84+
case CurrentProtocol.CommandId.REQ_ENTITY_SPAWN:
85+
Flk_API.APIClient.ReqEntitySpawn(payload[i], ref synchronizer);
86+
break;
87+
88+
case CurrentProtocol.CommandId.REQ_ENTITY_UPDATE:
89+
Flk_API.APIClient.ReqEntityUpdate(payload[i], ref synchronizer);
90+
break;
91+
92+
case CurrentProtocol.CommandId.REQ_ENTITY_DESTROY:
93+
Flk_API.APIClient.ReqEntityDestroy(payload[i], ref synchronizer);
94+
break;
95+
96+
case CurrentProtocol.CommandId.REQ_ENTITY_MOVED:
97+
Flk_API.APIClient.ReqEntityMoved(payload[i], ref synchronizer);
98+
break;
99+
100+
default:
101+
Debug.LogWarning("Unknown command ID received from the server.");
102+
break;
103+
}
104+
}
105+
}
106+
catch (Exception e)
107+
{
108+
Debug.LogError("Error in OnReceive: " + e.Message);
109+
}
110+
udpClient.BeginReceive(OnReceive, null);
111+
}
112+
113+
private void OnApplicationQuit()
114+
{
115+
if (!enable)
116+
return;
117+
enable = false;
118+
119+
udpClient.Close();
120+
}
121+
}

Libraries/Flakkari4Unity/README.md

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
# Flakkari4Unity
2+
3+
Flakkari4Unity is a Unity package that provides a simple way to use Flakkari Protocol in Unity projects to communicate with Flakkari server.
4+
5+
## Usage
6+
7+
```csharp
8+
using Flakkari4Unity;
9+
10+
public class Example : MonoBehaviour
11+
{
12+
private Flakkari4Unity flakkari;
13+
[SerializeField] private string serverIP = "127.0.0.1";
14+
[SerializeField] private int serverPort = 54000;
15+
[SerializeField] private string gameName = "SpaceWar";
16+
17+
private readonly Dictionary<CurrentProtocol.EventId, CurrentProtocol.EventState> axisEvents = new(4);
18+
19+
void Start()
20+
{
21+
NetworkClient networkClient = gameObject.AddComponent<NetworkClient>();
22+
networkClient.Create(serverIP, serverPort, gameName);
23+
}
24+
25+
public void FixedUpdate()
26+
{
27+
if (networkClient == null && networkClient.Enable)
28+
return;
29+
30+
List<CurrentProtocol.Event> events = new(8);
31+
Dictionary<CurrentProtocol.EventId, float> axisValues = new(4);
32+
33+
Net_HandleMovement(networkClient, ref events, ref axisValues);
34+
Net_HandleShooting(networkClient, ref events);
35+
36+
if (events.Count > 0 || axisValues.Count > 0)
37+
networkClient.Send(Flk_API.APIClient.ReqUserUpdates(events, axisValues));
38+
}
39+
40+
private void Net_HandleMovement(NetworkClient networkClient, ref List<CurrentProtocol.Event> events, ref Dictionary<CurrentProtocol.EventId, float> axisValues)
41+
{
42+
HandleNetworkInput("Fire2", CurrentProtocol.EventId.MOVE_FRONT, ref events);
43+
HandleNetworkInput("Fire1", CurrentProtocol.EventId.MOVE_BACK, ref events);
44+
45+
HandleMouseMovement("Horizontal", CurrentProtocol.EventId.LOOK_LEFT, CurrentProtocol.EventId.LOOK_RIGHT, ref axisValues);
46+
HandleMouseMovement("Vertical", CurrentProtocol.EventId.LOOK_DOWN, CurrentProtocol.EventId.LOOK_UP, ref axisValues);
47+
}
48+
49+
private void HandleNetworkInput(string inputName, CurrentProtocol.EventId eventId, ref List<CurrentProtocol.Event> events)
50+
{
51+
if (Input.GetButtonDown(inputName))
52+
events.Add(new CurrentProtocol.Event { id = eventId, state = CurrentProtocol.EventState.PRESSED });
53+
54+
else if (Input.GetButtonUp(inputName))
55+
events.Add(new CurrentProtocol.Event { id = eventId, state = CurrentProtocol.EventState.RELEASED });
56+
57+
}
58+
59+
private void HandleMouseMovement(string axisName, CurrentProtocol.EventId negativeEventId, CurrentProtocol.EventId positiveEventId , ref Dictionary<CurrentProtocol.EventId, float> axisValues)
60+
{
61+
float axisValue = Input.GetAxis(axisName);
62+
63+
if (axisValue < 0 && axisEvents[negativeEventId] != CurrentProtocol.EventState.PRESSED)
64+
{
65+
axisEvents[negativeEventId] = CurrentProtocol.EventState.PRESSED;
66+
axisEvents[positiveEventId] = CurrentProtocol.EventState.RELEASED;
67+
axisValues[negativeEventId] = axisValue;
68+
axisValues[positiveEventId] = 0;
69+
}
70+
else if (axisValue > 0 && axisEvents[positiveEventId] != CurrentProtocol.EventState.PRESSED)
71+
{
72+
axisEvents[positiveEventId] = CurrentProtocol.EventState.PRESSED;
73+
axisEvents[negativeEventId] = CurrentProtocol.EventState.RELEASED;
74+
axisValues[positiveEventId] = axisValue;
75+
axisValues[negativeEventId] = 0;
76+
}
77+
78+
if (axisValue == 0 && axisEvents[negativeEventId] == CurrentProtocol.EventState.PRESSED)
79+
{
80+
axisEvents[negativeEventId] = CurrentProtocol.EventState.RELEASED;
81+
axisValues[negativeEventId] = 0;
82+
}
83+
if (axisValue == 0 && axisEvents[positiveEventId] == CurrentProtocol.EventState.PRESSED)
84+
{
85+
axisEvents[positiveEventId] = CurrentProtocol.EventState.RELEASED;
86+
axisValues[positiveEventId] = 0;
87+
}
88+
}
89+
90+
private void Net_HandleShooting(NetworkClient networkClient, ref List<CurrentProtocol.Event> events)
91+
{
92+
if (Time.time - lastShotTime < cooldown)
93+
return;
94+
95+
HandleNetworkInput(KeyCode.Joystick1Button5, CurrentProtocol.EventId.SHOOT, ref events);
96+
}
97+
}
98+
```
99+
100+
## License
101+
102+
Flakkari4Unity is licensed under the MIT License. See the [LICENSE](LICENSE) file for more information.
103+
104+
## Contact
105+
106+
If you have any questions or feedback, please open an issue on the [GitHub repository](https://github.com/MasterLaplace/Flakkari/issues/new/choose).

0 commit comments

Comments
 (0)