This commit is contained in:
brausjonas
2022-05-12 11:02:58 +02:00
parent c147e5baea
commit 1429a95243
109 changed files with 9123 additions and 0 deletions
+55
View File
@@ -0,0 +1,55 @@
using System.Collections;
using System.Collections.Generic;
using System.Data.Common;
using UnityEngine;
public class Chunk
{
//basic
private ChunkCoord chunkPosition;
private World world;
//rendering
public GameObject gameObject;
//data
public byte[,,] blocks = new byte[Data.chunkWidth, Data.chunkHeight, Data.chunkWidth];
public Chunk(ChunkCoord chunkPosition, World world)
{
this.chunkPosition = chunkPosition;
this.world = world;
Initialize();
}
//initializes the chunks components
private void Initialize()
{
gameObject = new GameObject(chunkPosition.x + ", " + chunkPosition.z);
gameObject.transform.position =
new Vector3(chunkPosition.x * Data.chunkWidth, 0, chunkPosition.z * Data.chunkWidth);
}
//writes the block data
public void PopulateBlocks()
{
for (int y = 0; y < Data.chunkHeight; y++)
{
for (int x = 0; x < Data.chunkWidth; x++)
{
for (int z = 0; z < Data.chunkWidth; z++)
{
blocks[x, y, z] = world.GetBlockID(new Vector3(x + chunkPosition.x * Data.chunkWidth,
y, z + chunkPosition.z * Data.chunkWidth));
}
}
}
}
public void Update(byte x, byte y, byte z, byte blockID)
{
blocks[x, y, z] = blockID;
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a5d27935c6d501a41a2d972b8ff6cc7c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,17 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[Serializable]
public class ChunkCoord
{
public ChunkCoord(int x, int z)
{
this.x = x;
this.z = z;
}
public int x;
public int z;
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9b0ff680cf7becd4a905cd0f219efa91
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+53
View File
@@ -0,0 +1,53 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Data
{
public static int chunkWidth = 15, chunkHeight = 250;
public static int textureAtlasSize = 16;
public static readonly Vector3[] vertices =
{
new Vector3(0, 0, 0),
new Vector3(1, 0, 0),
new Vector3(1, 1, 0),
new Vector3(0, 1, 0),
new Vector3(1, 0, 1),
new Vector3(0, 0, 1),
new Vector3(0, 1, 1),
new Vector3(1, 1, 1)
};
public static readonly int[,] triangles =
{
//front
{0, 3, 1, 1, 3, 2},
//back
{4, 7, 5, 5, 7, 6},
//top
{3, 6, 2, 2, 6, 7},
//bottom
{5, 0, 4, 4, 0, 1},
//left
{5, 6, 0, 0, 6, 3},
//right
{1, 2, 4, 4, 2, 7},
};
public static readonly Vector3[] faceChecks =
{
//front
new Vector3(0, 0, -1),
//back
new Vector3(0, 0, 1),
//top
new Vector3(0, 1, 0),
//bottom
new Vector3(0, -1, 0),
//left
new Vector3(-1, 0, 0),
//right
new Vector3(1, 0, 0),
};
}
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 643914e5a873de34baea75d649800005
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+213
View File
@@ -0,0 +1,213 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using UnityEngine;
public class Server
{
//game
private World world;
//network
private UdpClient client;
private int transferDelay;
private List<IPEndPoint> players = new List<IPEndPoint>();
private List<string> playerNames = new List<string>();
private List<bool> nextTransfer = new List<bool>();
private Thread receiveThread;
private List<Thread> transferThreads = new List<Thread>();
public Server(World world, int transferDelay)
{
this.transferDelay = transferDelay;
this.world = world;
//setup client
client = new UdpClient(8051);
client.DontFragment = false;
//start listening
receiveThread = new Thread(Receive); //info:
receiveThread.Start();
//0: init message
}
//info:
//[0] = 0: init message
//[0] = 1: world transfer [1] = 1: finished
//[0] = 2: world size
//[0] = 3: edit block
//[0] = 4: disconnect player
//[0] = 5: next transfer
private void Receive()
{
try
{
while (true)
{
IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, 0);
byte[] data = client.Receive(ref endPoint);
if (data[0] == 5)
{
int id = GetPlayerID(endPoint);
nextTransfer[id] = true;
}
if (data[0] == 4)
{
IPEndPoint tempEndPoint = null;
int i = 0;
foreach (IPEndPoint e in players)
{
if (e.Address.GetHashCode() == endPoint.Address.GetHashCode())
{
Send(new byte[] { 4 }, e);
tempEndPoint = e;
break;
}
i++;
}
if (tempEndPoint != null)
{
players.Remove(tempEndPoint);
Console.WriteLine(playerNames[i] + " left the game");
playerNames.RemoveAt(i);
nextTransfer.RemoveAt(i);
}
}
if (data[0] == 0)
{
Thread t = new Thread(TransferWorld);
transferThreads.Add(t);
t.Start(endPoint);
}
if (data[0] == 2)
{
Send(new byte[] { 2, (byte)world.worldSize }, endPoint);
List<byte> asciiName = new List<byte>();
for (int i = 1; i < data.Length; i++)
{
asciiName.Add(data[i]);
}
string name = Encoding.ASCII.GetString(asciiName.ToArray());
//add player
players.Add(endPoint);
playerNames.Add(name);
nextTransfer.Add(false);
Console.WriteLine(name + " joined the game");
}
if (data[0] == 3)
{
ChunkCoord chunk = new ChunkCoord(data[1], data[2]);
Vector3 positionInChunk = new Vector3(data[3], data[4], data[5]);
byte blockID = data[6];
world.EditBlock(chunk, positionInChunk, blockID);
foreach (IPEndPoint e in players)
{
Send(new byte[]
{
3, (byte)chunk.x, (byte)chunk.z,
(byte)positionInChunk.x, (byte)positionInChunk.y, (byte)positionInChunk.z, blockID
}, e);
}
}
}
}
catch (Exception e)
{
}
}
private int GetPlayerID(IPEndPoint endPoint)
{
int i = 0;
foreach (IPEndPoint e in players)
{
if (e.Address.GetHashCode() == endPoint.Address.GetHashCode())
{
return i;
}
i++;
}
return -1;
}
private void TransferWorld(object o)
{
IPEndPoint endPoint = (IPEndPoint)o;
int id = GetPlayerID(endPoint);
Console.WriteLine("begin world transfer for " + playerNames[id]);
for (int xChunk = 0; xChunk < world.worldSize; xChunk++)
{
for (int zChunk = 0; zChunk < world.worldSize; zChunk++)
{
nextTransfer[id] = false;
byte[] send = new byte[Data.chunkWidth * Data.chunkWidth * Data.chunkHeight + 2];
send[0] = 1;
send[1] = 0;
int i = 2;
for (int y = 0; y < Data.chunkHeight; y++)
{
for (int x = 0; x < Data.chunkWidth; x++)
{
for (int z = 0; z < Data.chunkWidth; z++)
{
send[i] = world.chunks[xChunk, zChunk].blocks[x, y, z];
i++;
}
}
}
Send(send, endPoint);
while (!nextTransfer[id])
{
}
nextTransfer[id] = false;
}
}
Send(new byte[] { 1, 1 }, endPoint);
Console.WriteLine("world transfer finished for " + playerNames[id]);
}
private void Send(byte[] data, IPEndPoint endPoint)
{
client.Send(data, data.Length, endPoint);
}
public void Disconnect()
{
receiveThread.Abort();
for (int i = 0; i < transferThreads.Count; i++)
{
if (transferThreads[i] != null)
{
transferThreads[i].Abort();
}
}
client.Close();
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 40d9d5a5030b4944ea8c79b350ed5a0c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+151
View File
@@ -0,0 +1,151 @@
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class World : MonoBehaviour
{
//basic
[SerializeField] public int worldSize;
//chunks
public Chunk[,] chunks;
//network
private Server server;
[SerializeField] private int transferDelay;
private void Start()
{
CreateChunks();
server = new Server(this, transferDelay);
}
//creates an array of chunks
private void CreateChunks()
{
chunks = new Chunk[worldSize, worldSize];
for (int x = 0; x < worldSize; x++)
{
for (int z = 0; z < worldSize; z++)
{
chunks[x, z] = new Chunk(new ChunkCoord(x, z), this);
chunks[x, z].gameObject.transform.SetParent(gameObject.transform);
}
}
for (int x = 0; x < worldSize; x++)
{
for (int z = 0; z < worldSize; z++)
{
chunks[x, z].PopulateBlocks();
}
}
}
//return the ID of a block
public byte GetBlockID(Vector3 positionInWorld)
{
byte height = GetHeight((int)positionInWorld.x, (int)positionInWorld.z);
//world pass
if (positionInWorld.x < 0 || positionInWorld.y < 0 || positionInWorld.z < 0 ||
positionInWorld.x >= worldSize * Data.chunkWidth || positionInWorld.y > height ||
positionInWorld.z >= worldSize * Data.chunkWidth)
{
return 0;
}
//chunk pass
if ((int)positionInWorld.y == height)
{
return 3;
}
if ((int)positionInWorld.y == 0)
{
return 1;
}
if ((int)positionInWorld.y > height - 3)
{
return 2;
}
if ((int)positionInWorld.y < height)
{
return 4;
}
return 0;
}
//returns if a block is on the position
public bool CheckBlock(Vector3 positionInWorld)
{
if (positionInWorld.x < -1 || positionInWorld.z < -1 ||
positionInWorld.x > worldSize * Data.chunkWidth ||
positionInWorld.z > worldSize * Data.chunkWidth)
{
return false;
}
if (positionInWorld.x < 0 || positionInWorld.y < 0 || positionInWorld.z < 0 ||
positionInWorld.x >= worldSize * Data.chunkWidth || positionInWorld.y >= Data.chunkHeight ||
positionInWorld.z >= worldSize * Data.chunkWidth)
{
return true;
}
ChunkCoord chunk = new ChunkCoord((int)(positionInWorld.x / Data.chunkWidth),
(int)(positionInWorld.z / Data.chunkWidth));
int xInChunk = (int)(positionInWorld.x - chunk.x * Data.chunkWidth);
int yInChunk = (int)positionInWorld.y;
int zInChunk = (int)(positionInWorld.z - chunk.z * Data.chunkWidth);
if (chunks[chunk.x, chunk.z] != null)
{
if (chunks[chunk.x, chunk.z].blocks[xInChunk, yInChunk, zInChunk] == 0)
{
return false;
}
}
return true;
}
private byte GetHeight(int x, int z)
{
float scale = 0.025f;
byte perlinHeight = 10;
byte groundHeight = 10;
byte height = (byte)(Mathf.PerlinNoise((x) * scale + 0.1f, (z) * scale + 0.1f) * perlinHeight + groundHeight);
return height;
}
public void EditBlock(ChunkCoord chunk, Vector3 positionInChunk, byte blockID)
{
byte xInChunk = (byte)(positionInChunk.x);
byte yInChunk = (byte)positionInChunk.y;
byte zInChunk = (byte)(positionInChunk.z);
//edit block in chunk
if(chunks[chunk.x, chunk.z].blocks[xInChunk, yInChunk, zInChunk] != 1)
{
chunks[chunk.x, chunk.z].Update(xInChunk, yInChunk, zInChunk, blockID);
}
}
private void OnApplicationQuit()
{
server.Disconnect();
}
private void SaveWorld()
{
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5457f26f725053d46bffb9885acfd7d8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: