Skip to content

Commit 6e822c6

Browse files
committed
first commit
0 parents  commit 6e822c6

102 files changed

Lines changed: 5882 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Cs2dJavaMapLibrary
2+
3+
early alpha development, expect bugs.

pom.xml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
2+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
3+
<modelVersion>4.0.0</modelVersion>
4+
<groupId>net.ddns.endercrypt.cs2dmap.library</groupId>
5+
<artifactId>Cs2dMapLibrary</artifactId>
6+
<version>0.0.1-SNAPSHOT</version>
7+
8+
<dependencies>
9+
<dependency>
10+
<groupId>io.github.lukehutch</groupId>
11+
<artifactId>fast-classpath-scanner</artifactId>
12+
<version>2.9.3</version>
13+
</dependency>
14+
</dependencies>
15+
16+
</project>
Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
package net.ddns.endercypt.cs2dmap.library.file.read;
2+
3+
import java.io.File;
4+
import java.io.FileNotFoundException;
5+
import java.io.IOException;
6+
import java.util.ArrayList;
7+
import java.util.List;
8+
9+
import net.ddns.endercypt.cs2dmap.library.file.read.stream.Cs2dByteReader;
10+
import net.ddns.endercypt.cs2dmap.library.file.read.stream.Cs2dMapReadException;
11+
import net.ddns.endercypt.cs2dmap.library.file.stream.assist.Cs2dByteInfo;
12+
import net.ddns.endercypt.cs2dmap.library.file.stream.exception.Cs2dUnexpectedEOFException;
13+
import net.ddns.endercypt.cs2dmap.library.map.Cs2dMap;
14+
import net.ddns.endercypt.cs2dmap.library.raw.RawCs2dEntity;
15+
import net.ddns.endercypt.cs2dmap.library.raw.RawCs2dMap;
16+
import net.ddns.endercypt.cs2dmap.library.raw.RawCs2dTile;
17+
import net.ddns.endercypt.cs2dmap.library.raw.rawbyte.RawByte;
18+
import net.ddns.endercypt.cs2dmap.library.raw.rawbyte.RawByteFlags;
19+
20+
public class Cs2dMapReader
21+
{
22+
public static Cs2dMap read(File file) throws FileNotFoundException, IOException
23+
{
24+
RawCs2dMap rawCs2dMap = new RawCs2dMap();
25+
26+
try (Cs2dByteReader reader = new Cs2dByteReader(file))
27+
{
28+
// (1) HEADER
29+
rawCs2dMap.header = reader.readString();
30+
31+
// ----- 10 bytes for map settings / info
32+
rawCs2dMap.scroll_map_like_tiles = reader.readBooleanByte();
33+
boolean use_modifiers_in_this_map = reader.readBooleanByte().value;
34+
rawCs2dMap.save_tile_heights_with_map = reader.readByte();
35+
rawCs2dMap.use_64x64_pixel_tiles = reader.readBooleanByte();
36+
reader.skip(Cs2dByteInfo.BYTE, 6);
37+
38+
// ----- 10 ints for map settings / info
39+
rawCs2dMap.uptime_of_system = reader.readInt();
40+
rawCs2dMap.usgn_id_of_the_map_author = reader.readInt();
41+
rawCs2dMap.map_daylight_time = reader.readInt();
42+
reader.skip(Cs2dByteInfo.INT, 7);
43+
44+
// ----- 10 strings for map settings / info
45+
rawCs2dMap.name_of_the_map_author = reader.readString();
46+
rawCs2dMap.name_of_the_program_used_to_save_the_map = reader.readString();
47+
reader.skipStringNulls(8);
48+
49+
// ----- More map settings
50+
String[] tempStringArray = split(reader.readString(), new char[] { 'x', '$', '%' });
51+
int map_xy_size = Integer.parseInt(tempStringArray[0]);
52+
rawCs2dMap.tile_count = Integer.parseInt(tempStringArray[1]);
53+
rawCs2dMap.currentSystemTime = Integer.parseInt(tempStringArray[2]);
54+
rawCs2dMap.systemUpTime = Long.parseLong(tempStringArray[3]);
55+
rawCs2dMap.filename_of_the_tilset_image = reader.readString();
56+
//rawCs2dMap.number_of_tiles_required_from_this_tileset = reader.readByte();
57+
reader.readByte(); // skip number_of_tiles_required_from_this_tileset as its auto-generated during write
58+
rawCs2dMap.map_width = reader.readInt();
59+
rawCs2dMap.map_height = reader.readInt();
60+
if (rawCs2dMap.map_width * rawCs2dMap.map_height != map_xy_size)
61+
{
62+
throw new Cs2dMapReadException("(map_xsize (in tiles) * map_ysize (in tiles)) = " + map_xy_size + " of the map file is inconsistant with the map width/height (" + rawCs2dMap.map_width + "," + rawCs2dMap.map_height + "=" + (rawCs2dMap.map_width * rawCs2dMap.map_height) + ")");
63+
}
64+
rawCs2dMap.filename_of_map_background_image = reader.readString();
65+
rawCs2dMap.background_scroll_x_speed = reader.readInt();
66+
rawCs2dMap.background_scroll_y_speed = reader.readInt();
67+
rawCs2dMap.map_background_color_red = reader.readByte();
68+
rawCs2dMap.map_background_color_green = reader.readByte();
69+
rawCs2dMap.map_background_color_blue = reader.readByte();
70+
71+
// ----- Header Test
72+
if (reader.readString().equals(Cs2dByteInfo.REVERSE_UNREALSOFTWARE) == false)
73+
{
74+
throw new Cs2dMapReadException("header check failed: " + Cs2dByteInfo.REVERSE_UNREALSOFTWARE);
75+
}
76+
77+
// (2) Tile Modes
78+
rawCs2dMap.tile_modes = new RawByte[rawCs2dMap.tile_count + 1];
79+
for (int i = 0; i < rawCs2dMap.tile_count + 1; i++)
80+
{
81+
rawCs2dMap.tile_modes[i] = reader.readByte();
82+
}
83+
84+
// (3) Tile Heights
85+
switch (rawCs2dMap.save_tile_heights_with_map.getInt())
86+
{
87+
case 0:
88+
// READ (ignore)
89+
// UPGRADE TO MODE 2
90+
rawCs2dMap.save_tile_heights_with_map.set(2);
91+
rawCs2dMap.tile_height_in_pixels = new int[rawCs2dMap.tile_count + 1];
92+
rawCs2dMap.tile_3D_modifier = new RawByteFlags[rawCs2dMap.tile_count + 1];
93+
for (int i = 0; i < rawCs2dMap.tile_count + 1; i++)
94+
{
95+
rawCs2dMap.tile_height_in_pixels[i] = 0;
96+
rawCs2dMap.tile_3D_modifier[i] = RawByteFlags.EMPTY();
97+
}
98+
break;
99+
case 1: // If "save tile heights" is 1 (only used in 1.0.0.3 pre-release):
100+
// READ
101+
rawCs2dMap.tile_height_in_pixels = new int[rawCs2dMap.tile_count + 1];
102+
for (int i = 0; i < rawCs2dMap.tile_count + 1; i++)
103+
{
104+
rawCs2dMap.tile_height_in_pixels[i] = reader.readInt();
105+
}
106+
// UPGRADE TO MODE 2
107+
rawCs2dMap.save_tile_heights_with_map.set(2);
108+
rawCs2dMap.tile_3D_modifier = new RawByteFlags[rawCs2dMap.tile_count + 1];
109+
for (int i = 0; i < rawCs2dMap.tile_count + 1; i++)
110+
{
111+
rawCs2dMap.tile_3D_modifier[i] = RawByteFlags.EMPTY();
112+
}
113+
break;
114+
case 2: // Else If "save tile heights" is 2 (default since 1.0.0.3):
115+
// READ
116+
rawCs2dMap.tile_height_in_pixels = new int[rawCs2dMap.tile_count + 1];
117+
rawCs2dMap.tile_3D_modifier = new RawByteFlags[rawCs2dMap.tile_count + 1];
118+
for (int i = 0; i < rawCs2dMap.tile_count + 1; i++)
119+
{
120+
rawCs2dMap.tile_height_in_pixels[i] = reader.readShort() & 0xFFFF;
121+
rawCs2dMap.tile_3D_modifier[i] = reader.readRawByteFlags();
122+
}
123+
break;
124+
default:
125+
throw new Cs2dMapReadException("byte \"use modifiers in this map\" contained unknown value: " + rawCs2dMap.save_tile_heights_with_map.getByte());
126+
}
127+
128+
// (4) Map
129+
rawCs2dMap.map = new RawCs2dTile[rawCs2dMap.map_width + 1][rawCs2dMap.map_height + 1];
130+
for (int x = 0; x < rawCs2dMap.map_width + 1; x++)
131+
{
132+
for (int y = 0; y < rawCs2dMap.map_height + 1; y++)
133+
{
134+
rawCs2dMap.map[x][y] = new RawCs2dTile(reader);
135+
}
136+
}
137+
if (use_modifiers_in_this_map)
138+
{
139+
for (int x = 0; x < rawCs2dMap.map_width + 1; x++)
140+
{
141+
for (int y = 0; y < rawCs2dMap.map_height + 1; y++)
142+
{
143+
rawCs2dMap.map[x][y].readModifiers(reader);
144+
}
145+
}
146+
}
147+
148+
// (5) Entities
149+
int entity_count = reader.readInt();
150+
for (int i = 0; i < entity_count; i++)
151+
{
152+
rawCs2dMap.entities.add(new RawCs2dEntity(reader));
153+
}
154+
155+
// (6) End of file
156+
if (reader.available() > 0)
157+
{
158+
throw new Cs2dUnexpectedEOFException("read a total of " + reader.getPosition() + " bytes and expected EOF but found ~" + reader.available() + " residual bytes!", reader.getPosition(), reader.dumpStream());
159+
}
160+
}
161+
162+
return new Cs2dMap(rawCs2dMap);
163+
}
164+
165+
private static String[] split(String string, char[] pattern)
166+
{
167+
List<String> array = new ArrayList<>();
168+
for (int i = 0; i < pattern.length; i++)
169+
{
170+
char patternCharacter = pattern[i];
171+
int location = string.indexOf(patternCharacter);
172+
if (location == -1)
173+
{
174+
throw new Cs2dMapReadException("unable to find pattern " + patternCharacter + " in string " + string);
175+
}
176+
String element = string.substring(0, location);
177+
array.add(element);
178+
string = string.substring(location + 1);
179+
}
180+
array.add(string);
181+
return array.stream().toArray(String[]::new);
182+
}
183+
}
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
package net.ddns.endercypt.cs2dmap.library.file.read.stream;
2+
3+
import java.io.BufferedInputStream;
4+
import java.io.ByteArrayOutputStream;
5+
import java.io.File;
6+
import java.io.FileInputStream;
7+
import java.io.FileNotFoundException;
8+
import java.io.IOException;
9+
import java.nio.ByteBuffer;
10+
11+
import net.ddns.endercypt.cs2dmap.library.file.stream.Cs2dAbstractIOStream;
12+
import net.ddns.endercypt.cs2dmap.library.file.stream.assist.Cs2dByteInfo;
13+
import net.ddns.endercypt.cs2dmap.library.raw.rawbyte.BooleanByte;
14+
import net.ddns.endercypt.cs2dmap.library.raw.rawbyte.RawByte;
15+
import net.ddns.endercypt.cs2dmap.library.raw.rawbyte.RawByteFlags;
16+
17+
public class Cs2dByteReader extends Cs2dAbstractIOStream<BufferedInputStream>
18+
{
19+
public Cs2dByteReader(File file) throws FileNotFoundException
20+
{
21+
super(new BufferedInputStream(new FileInputStream(file)));
22+
}
23+
24+
// PRIVATE
25+
26+
private byte[] rawRead(int bytes) throws IOException
27+
{
28+
byte[] byteArray = new byte[bytes];
29+
for (int i = 0; i < bytes; i++)
30+
{
31+
int raw = getStream().read();
32+
if (raw == -1)
33+
{
34+
throw new Cs2dMapReadException("Reached end of stream unexpectedly");
35+
}
36+
byteArray[i] = (byte) raw;
37+
}
38+
advancePosition(bytes);
39+
return byteArray;
40+
}
41+
42+
private ByteBuffer rawReadBytes(int bytes) throws IOException
43+
{
44+
byte[] byteArray = rawRead(bytes);
45+
ByteBuffer bb = ByteBuffer.allocate(bytes);
46+
bb.order(Cs2dByteInfo.ENDIAN);
47+
bb.put(byteArray);
48+
return bb;
49+
}
50+
51+
// NULL
52+
53+
public void skipCharacters(int count, byte[] pattern) throws IOException
54+
{
55+
for (int i = 0; i < count; i++)
56+
{
57+
byte[] bytes = rawRead(pattern.length);
58+
for (int ii = 0; ii < pattern.length; ii++)
59+
{
60+
byte expected = pattern[ii];
61+
byte got = bytes[ii];
62+
if (got != expected)
63+
throw new Cs2dMapReadException("recieved " + got + " (" + (char) got + ") when trying to skip characters, expected " + expected + " (" + (char) expected + ")");
64+
}
65+
}
66+
}
67+
68+
public void skip(int size, int count) throws IOException
69+
{
70+
byte[] pattern = new byte[size];
71+
for (int i = 0; i < pattern.length; i++)
72+
{
73+
pattern[i] = '\00';
74+
}
75+
skipCharacters(count, pattern);
76+
}
77+
78+
public void skipStringNulls(int count) throws IOException
79+
{
80+
skipCharacters(count, new byte[] { '\r', '\n' });
81+
}
82+
83+
// BYTE
84+
85+
public RawByte readByte() throws IOException
86+
{
87+
return new RawByte(rawReadBytes(Cs2dByteInfo.BYTE).get(0));
88+
}
89+
90+
public BooleanByte readBooleanByte() throws IOException
91+
{
92+
return new BooleanByte(readByte());
93+
}
94+
95+
public RawByteFlags readRawByteFlags() throws IOException
96+
{
97+
return new RawByteFlags(readByte());
98+
}
99+
100+
// SHORT
101+
102+
public short readShort() throws IOException
103+
{
104+
return rawReadBytes(Cs2dByteInfo.SHORT).getShort(0);
105+
}
106+
107+
// INTEGER
108+
109+
public int readInt() throws IOException
110+
{
111+
return rawReadBytes(Cs2dByteInfo.INT).getInt(0);
112+
}
113+
114+
// LONG
115+
116+
public long readLong() throws IOException
117+
{
118+
return rawReadBytes(Cs2dByteInfo.LONG).getLong(0);
119+
}
120+
121+
// STRING
122+
123+
public String readString() throws IOException
124+
{
125+
StringBuilder sb = new StringBuilder();
126+
int byteCharacter = 0;
127+
while ((byteCharacter = getStream().read()) != '\r')
128+
{
129+
sb.append((char) byteCharacter);
130+
}
131+
if (getStream().read() != '\n')
132+
throw new Cs2dMapReadException("Expected newline");
133+
advancePosition(sb.length() + 2);
134+
return sb.toString();
135+
}
136+
137+
// EXTRA
138+
139+
public int available() throws IOException
140+
{
141+
return getStream().available();
142+
}
143+
144+
public byte[] dumpStream() throws IOException
145+
{
146+
// possibly replace with ioutils for copying streams or getting byte array
147+
ByteArrayOutputStream byteArray = new ByteArrayOutputStream((int) (available() * 1.1));
148+
int value = -1;
149+
while ((value = getStream().read()) != -1)
150+
{
151+
byteArray.write(value);
152+
}
153+
advancePosition(byteArray.size());
154+
return byteArray.toByteArray();
155+
}
156+
}

0 commit comments

Comments
 (0)