summaryrefslogtreecommitdiff
path: root/server
diff options
context:
space:
mode:
Diffstat (limited to 'server')
-rw-r--r--server/main.ha63
1 files changed, 54 insertions, 9 deletions
diff --git a/server/main.ha b/server/main.ha
index ae7d9eb..30e5e0a 100644
--- a/server/main.ha
+++ b/server/main.ha
@@ -14,6 +14,7 @@ use unix::poll;
use drawing;
use drawing::{pos};
use packet_reader;
+use bytes;
def PORT: u16 = 41460;
@@ -31,17 +32,11 @@ export fn main() void = {
let pictures: []drawing::picture = alloc([],len(offs));
for (let i = 0z; i < len(offs); i +=1){
- append(pictures, drawing::picture {
- w = CHUNKSIZE,
- h = CHUNKSIZE,
- d = alloc([0...],CHUNKSIZE*CHUNKSIZE: size): *[*]u32,
- world_pos = offs[i],
- });
+ append(pictures, load_picture_from_file(offs[i])!);
};
- for (const p &.. pictures) drawing::clear_picture(p, 0xffffff);
- const listener = match(tcp::listen(ip::ANY_V4, PORT)) {
+ const listener = match(tcp::listen(ip::ANY_V4, PORT, tcp::reuseaddr)) {
case let err: net::error =>
fmt::fatalf(net::strerror(err));
case let sock: net::socket =>
@@ -53,10 +48,14 @@ export fn main() void = {
def save_interval = 20 * time::SECOND;
+// caller should free return value
+fn filename_from_world_pos(pos: pos) str =
+ fmt::asprintf("./c.{}.{}.ppm",pos.0,pos.1);
+
fn save_world(pictures: []drawing::picture) void = {
fmt::printfln("saving world!")!;
for (const pic &.. pictures) {
- const filename = fmt::asprintf("./c.{}.{}.ppm",pic.world_pos.0, pic.world_pos.1);
+ const filename = filename_from_world_pos(pic.world_pos);
fmt::printfln("\t-> {}",filename)!;
defer free(filename);
const mode = fs::mode::USER_RW | fs::mode::GROUP_RW;
@@ -83,6 +82,52 @@ fn save_world(pictures: []drawing::picture) void = {
};
+type bad_header = !void;
+fn load_picture_from_file(world_pos: pos) (drawing::picture | fs::error | bad_header) = {
+ const filename = filename_from_world_pos(world_pos);
+ defer free(filename);
+ const file = os::open(filename)?;
+ fmt::printfln("reading from {}",filename)!;
+ defer {
+ fmt::printfln("closing {}",filename)!;
+ match (io::close(file)) {
+ case let err: io::error => fmt::println("error",io::strerror(err))!;
+ case => yield;
+ };
+ };
+
+ const header = fmt::asprintf("P6\n{} {}\n{}\n",CHUNKSIZE,CHUNKSIZE,255);
+ defer free(header);
+ const header_bytes = strings::toutf8(header);
+ let header_buf: []u8 = alloc([0...],len(header_bytes));
+ defer free(header_buf);
+ io::readall(file, header_buf)?;
+ if (!bytes::equal(header_buf, header_bytes)) return bad_header;
+
+ let file_buf: []u8 = alloc([0...], 3*CHUNKSIZE*CHUNKSIZE);
+ defer free(file_buf);
+ io::readall(file, file_buf)?;
+ let picture_buf: []u32 = alloc([0...], CHUNKSIZE*CHUNKSIZE);
+ for (let i = 0z; i < len(picture_buf); i += 1) {
+ picture_buf[i] = (file_buf[3*i]:u32<<16)
+ |(file_buf[3*i+1]:u32<<8)
+ |(file_buf[3*i+2]:u32);
+ if (picture_buf[i] != 0xffffff) fmt::println(i,picture_buf[i])!;
+ };
+ return drawing::picture {
+ w = CHUNKSIZE,
+ h = CHUNKSIZE,
+ d = picture_buf: *[*]u32,
+ world_pos = world_pos,
+ };
+};
+
+
+
+
+
+
+
fn loop(listener: net::socket, pictures: []drawing::picture) void = {
// pollfds[0] is the listener
// pollfds[n>0] corresponds to packet_readers[n-1]