Add support for importing .fcm files from ProCraft with custom blocks, also use nicer constant names for Block.doorX blocks.

This commit is contained in:
UnknownShadow200 2016-02-27 12:36:14 +11:00
parent a0b9bd6696
commit bfb535c88d
10 changed files with 306 additions and 218 deletions

View File

@ -35,15 +35,17 @@ namespace MCGalaxy.Commands {
if (!Directory.Exists("extra/import"))
Directory.CreateDirectory("extra/import");
if (File.Exists(file + ".dat")) { Import(p, file + ".dat", message, false); return; }
if (File.Exists(file + ".mcf")) { Import(p, file + ".mcf", message, true); return; }
Player.SendMessage(p, "No .dat or .mcf file with the given name was found in the imports directory.");
if (File.Exists(file + ".dat")) { Import(p, file + ".dat", message, FileType.Dat); return; }
if (File.Exists(file + ".mcf")) { Import(p, file + ".mcf", message, FileType.Mcf); return; }
if (File.Exists(file + ".fcm")) { Import(p, file + ".fcm", message, FileType.Fcm); return; }
Player.SendMessage(p, "No .dat, .mcf or .fcm file with the given name was found in the imports directory.");
}
void Import(Player p, string fileName, string message, bool mcf) {
void Import(Player p, string fileName, string message, FileType type) {
using (FileStream fs = File.OpenRead(fileName)) {
try {
if (mcf) McfFile.Load(fs, message);
if (type == FileType.Mcf) McfFile.Load(fs, message);
else if (type == FileType.Fcm) FcmFile.Load(fs, message);
else DatFile.Load(fs, message);
} catch (Exception ex) {
Server.ErrorLog(ex);
@ -54,10 +56,12 @@ namespace MCGalaxy.Commands {
}
}
enum FileType { Mcf, Fcm, Dat };
public override void Help(Player p) {
Player.SendMessage(p, "%T/import [name]");
Player.SendMessage(p, "%HImports the .dat or .mcf file with the given name.");
Player.SendMessage(p, "%HNote this command only loads .dat/.mcf files from the /extra/import/ folder");
Player.SendMessage(p, "%HImports the .dat, .mcf or .fcm file with the given name.");
Player.SendMessage(p, "%HNote this command only loads .dat/.mcf/.fcm files from the /extra/import/ folder");
}
}
}

View File

@ -106,17 +106,17 @@ namespace MCGalaxy
case lava_sponge: return "lava_sponge";
case wood_float: return "wood_float"; //TODO
case door: return "door_wood";
case door_tree: return "door_wood";
case lava_fast: return "lava_fast";
case door2: return "door_obsidian";
case door3: return "door_glass";
case door4: return "door_stone";
case door5: return "door_leaves";
case door6: return "door_sand";
case door7: return "door_wood";
case door8: return "door_green";
case door9: return "door_tnt";
case door10: return "door_stair";
case door_obsidian: return "door_obsidian";
case door_glass: return "door_glass";
case door_stone: return "door_stone";
case door_leaves: return "door_leaves";
case door_sand: return "door_sand";
case door_wood: return "door_wood";
case door_green: return "door_green";
case door_tnt: return "door_tnt";
case door_stair: return "door_stair";
case door_iron: return "door_iron";
case door_gold: return "door_gold";
case door_cobblestone: return "door_cobblestone";
@ -232,23 +232,23 @@ namespace MCGalaxy
//Blocks after this are converted before saving
case air_flood: return "air_flood";
case door_air: return "door_air";
case door_tree__air: return "door_air";
case air_flood_layer: return "air_flood_layer";
case air_flood_down: return "air_flood_down";
case air_flood_up: return "air_flood_up";
case door2_air: return "door2_air";
case door3_air: return "door3_air";
case door4_air: return "door4_air";
case door5_air: return "door5_air";
case door6_air: return "door6_air";
case door7_air: return "door7_air";
case door8_air: return "door8_air";
case door9_air: return "door9_air";
case door10_air: return "door10_air";
case door11_air: return "door11_air";
case door12_air: return "door12_air";
case door13_air: return "door13_air";
case door14_air: return "door14_air";
case door_obsidian_air: return "door2_air";
case door_glass_air: return "door3_air";
case door_stone_air: return "door4_air";
case door_leaves_air: return "door5_air";
case door_sand_air: return "door6_air";
case door_wood_air: return "door7_air";
case door_green_air: return "door8_air";
case door_tnt_air: return "door9_air";
case door_stair_air: return "door10_air";
case air_switch_air: return "door11_air";
case water_door_air: return "door12_air";
case lava_door_air: return "door13_air";
case air_door_air: return "door14_air";
case door_iron_air: return "door_iron_air";
case door_gold_air: return "door_gold_air";
case door_dirt_air: return "door_dirt_air";
@ -387,26 +387,26 @@ namespace MCGalaxy
case "wood_float": return wood_float; //TODO
case "lava_fast": return lava_fast;
case "door_tree":
case "door": return door;
case "door_obsidian":
case "door2": return door2;
case "door_glass":
case "door3": return door3;
case "door_stone":
case "door4": return door4;
case "door_leaves":
case "door5": return door5;
case "door_sand":
case "door6": return door6;
case "door_wood":
case "door7": return door7;
case "door_green":
case "door8": return door8;
case "door_tnt":
case "door9": return door9;
case "door_stair":
case "door10": return door10;
case "door":
case "door_tree": return door_tree;
case "door2":
case "door_obsidian": return door_obsidian;
case "door3":
case "door_glass": return door_glass;
case "door4":
case "door_stone": return door_stone;
case "door5":
case "door_leaves": return door_leaves;
case "door6":
case "door_sand": return door_sand;
case "door7":
case "door_wood": return door_wood;
case "door8":
case "door_green": return door_green;
case "door9":
case "door_tnt": return door_tnt;
case "door10":
case "door_stair": return door_stair;
case "door11":
case "door_iron": return door_iron;
case "door12":
@ -550,20 +550,20 @@ namespace MCGalaxy
case "air_flood_layer": return air_flood_layer;
case "air_flood_down": return air_flood_down;
case "air_flood_up": return air_flood_up;
case "door_air": return door_air;
case "door2_air": return door2_air;
case "door3_air": return door3_air;
case "door4_air": return door4_air;
case "door5_air": return door5_air;
case "door6_air": return door6_air;
case "door7_air": return door7_air;
case "door8_air": return door8_air;
case "door9_air": return door9_air;
case "door10_air": return door10_air;
case "door11_air": return door11_air;
case "door12_air": return door12_air;
case "door13_air": return door13_air;
case "door14_air": return door14_air;
case "door_air": return door_tree__air;
case "door2_air": return door_obsidian_air;
case "door3_air": return door_glass_air;
case "door4_air": return door_stone_air;
case "door5_air": return door_leaves_air;
case "door6_air": return door_sand_air;
case "door7_air": return door_wood_air;
case "door8_air": return door_green_air;
case "door9_air": return door_tnt_air;
case "door10_air": return door_stair_air;
case "door11_air": return air_switch_air;
case "door12_air": return water_door_air;
case "door13_air": return lava_door_air;
case "door14_air": return air_door_air;
case "door_iron_air": return door_iron_air;
case "door_dirt_air": return door_dirt_air;
case "door_grass_air": return door_grass_air;
@ -650,16 +650,16 @@ namespace MCGalaxy
case 71:
case 72:
return Block.white;
case door: return trunk;//door show by treetype
case door2: return obsidian;//door show by obsidian
case door3: return glass;//door show by glass
case door4: return rock;//door show by stone
case door5: return leaf;//door show by leaves
case door6: return sand;//door show by sand
case door7: return wood;//door show by wood
case door8: return green;
case door9: return tnt;//door show by TNT
case door10: return staircasestep;//door show by Stair
case door_tree: return trunk;//door show by treetype
case door_obsidian: return obsidian;//door show by obsidian
case door_glass: return glass;//door show by glass
case door_stone: return rock;//door show by stone
case door_leaves: return leaf;//door show by leaves
case door_sand: return sand;//door show by sand
case door_wood: return wood;//door show by wood
case door_green: return green;
case door_tnt: return tnt;//door show by TNT
case door_stair: return staircasestep;//door show by Stair
case door_iron: return iron;
case door_dirt: return dirt;
case door_grass: return grass;
@ -762,21 +762,21 @@ namespace MCGalaxy
case Block.checkpoint: return Block.air;
case air_flood:
case door_air:
case door_tree__air:
case air_flood_layer:
case air_flood_down:
case air_flood_up:
case door2_air:
case door3_air:
case door4_air:
case door5_air:
case door6_air:
case door7_air:
case door10_air:
case door11_air:
case door12_air:
case door13_air:
case door14_air:
case door_obsidian_air:
case door_glass_air:
case door_stone_air:
case door_leaves_air:
case door_sand_air:
case door_wood_air:
case door_stair_air:
case air_switch_air:
case water_door_air:
case lava_door_air:
case air_door_air:
case door_iron_air:
case door_gold_air:
case door_cobblestone_air:
@ -790,8 +790,8 @@ namespace MCGalaxy
case door_lightgrey_air:
case door_white_air:
return air;
case door8_air: return red;
case door9_air: return lava;
case door_green_air: return red;
case door_tnt_air: return lava;
case odoor1_air:
case odoor2_air:
@ -845,20 +845,20 @@ namespace MCGalaxy
case air_flood_down:
case air_flood_up:
return air; //air_flood must be converted to air on save to prevent issues
case door_air: return door;
case door2_air: return door2;
case door3_air: return door3;
case door4_air: return door4;
case door5_air: return door5;
case door6_air: return door6;
case door7_air: return door7;
case door8_air: return door8;
case door9_air: return door9;
case door10_air: return door10;
case door11_air: return air_switch;
case door12_air: return water_door;
case door13_air: return lava_door;
case door14_air: return air_door;
case door_tree__air: return door_tree;
case door_obsidian_air: return door_obsidian;
case door_glass_air: return door_glass;
case door_stone_air: return door_stone;
case door_leaves_air: return door_leaves;
case door_sand_air: return door_sand;
case door_wood_air: return door_wood;
case door_green_air: return door_green;
case door_tnt_air: return door_tnt;
case door_stair_air: return door_stair;
case air_switch_air: return air_switch;
case water_door_air: return water_door;
case lava_door_air: return lava_door;
case air_door_air: return air_door;
case door_iron_air: return door_iron;
case door_gold_air: return door_gold;
case door_dirt_air: return door_dirt;

View File

@ -141,17 +141,17 @@ namespace MCGalaxy
public const byte lava_sponge = (byte)109;
public const byte wood_float = (byte)110;
public const byte door = (byte)111;
public const byte door_tree = (byte)111;
public const byte lava_fast = (byte)112;
public const byte door2 = (byte)113;
public const byte door3 = (byte)114;
public const byte door4 = (byte)115;
public const byte door5 = (byte)116;
public const byte door6 = (byte)117;
public const byte door7 = (byte)118;
public const byte door8 = (byte)119;
public const byte door9 = (byte)120;
public const byte door10 = (byte)121;
public const byte door_obsidian = (byte)113;
public const byte door_glass = (byte)114;
public const byte door_stone = (byte)115;
public const byte door_leaves = (byte)116;
public const byte door_sand = (byte)117;
public const byte door_wood = (byte)118;
public const byte door_green = (byte)119;
public const byte door_tnt = (byte)120;
public const byte door_stair = (byte)121;
public const byte tdoor = (byte)122;
public const byte tdoor2 = (byte)123;
@ -255,23 +255,23 @@ namespace MCGalaxy
public const byte checkpoint = (byte)197;
public const byte air_flood = (byte)200;
public const byte door_air = (byte)201;
public const byte door_tree__air = (byte)201;
public const byte air_flood_layer = (byte)202;
public const byte air_flood_down = (byte)203;
public const byte air_flood_up = (byte)204;
public const byte door2_air = (byte)205;
public const byte door3_air = (byte)206;
public const byte door4_air = (byte)207;
public const byte door5_air = (byte)208;
public const byte door6_air = (byte)209;
public const byte door7_air = (byte)210;
public const byte door8_air = (byte)211;
public const byte door9_air = (byte)212;
public const byte door10_air = (byte)213;
public const byte door11_air = (byte)214;
public const byte door12_air = (byte)215;
public const byte door13_air = (byte)216;
public const byte door14_air = (byte)217;
public const byte door_obsidian_air = (byte)205;
public const byte door_glass_air = (byte)206;
public const byte door_stone_air = (byte)207;
public const byte door_leaves_air = (byte)208;
public const byte door_sand_air = (byte)209;
public const byte door_wood_air = (byte)210;
public const byte door_green_air = (byte)211;
public const byte door_tnt_air = (byte)212;
public const byte door_stair_air = (byte)213;
public const byte air_switch_air = (byte)214;
public const byte water_door_air = (byte)215;
public const byte lava_door_air = (byte)216;
public const byte air_door_air = (byte)217;
public const byte door_iron = (byte)220;
public const byte door_dirt = (byte)221;

View File

@ -122,20 +122,20 @@ namespace MCGalaxy
case wood_float:
case lava_sponge:
case door_air:
case door2_air:
case door3_air:
case door4_air:
case door5_air:
case door6_air:
case door7_air:
case door8_air:
case door9_air:
case door10_air:
case door11_air:
case door12_air:
case door13_air:
case door14_air:
case door_tree__air:
case door_obsidian_air:
case door_glass_air:
case door_stone_air:
case door_leaves_air:
case door_sand_air:
case door_wood_air:
case door_green_air:
case door_tnt_air:
case door_stair_air:
case air_switch_air:
case water_door_air:
case lava_door_air:
case air_door_air:
case door_iron_air:
case door_gold_air:
case door_cobblestone_air:
@ -208,16 +208,16 @@ namespace MCGalaxy
b.lowestRank = LevelPermission.AdvBuilder;
break;
case door:
case door2:
case door3:
case door4:
case door5:
case door6:
case door7:
case door8:
case door9:
case door10:
case door_tree:
case door_obsidian:
case door_glass:
case door_stone:
case door_leaves:
case door_sand:
case door_wood:
case door_green:
case door_tnt:
case door_stair:
case air_door:
case air_switch:
case water_door:

View File

@ -50,16 +50,16 @@ namespace MCGalaxy
case Block.MsgWhite:
case Block.MsgBlack:
case Block.door:
case Block.door2:
case Block.door3:
case Block.door4:
case Block.door5:
case Block.door6:
case Block.door7:
case Block.door8:
case Block.door9:
case Block.door10:
case Block.door_tree:
case Block.door_obsidian:
case Block.door_glass:
case Block.door_stone:
case Block.door_leaves:
case Block.door_sand:
case Block.door_wood:
case Block.door_green:
case Block.door_tnt:
case Block.door_stair:
case door_iron:
case door_gold:
case door_dirt:
@ -392,16 +392,16 @@ namespace MCGalaxy
case Block.op_air:
case Block.op_water:
case Block.door:
case Block.door2:
case Block.door3:
case Block.door4:
case Block.door5:
case Block.door6:
case Block.door7:
case Block.door8:
case Block.door9:
case Block.door10:
case Block.door_tree:
case Block.door_obsidian:
case Block.door_glass:
case Block.door_stone:
case Block.door_leaves:
case Block.door_sand:
case Block.door_wood:
case Block.door_green:
case Block.door_tnt:
case Block.door_stair:
case door_iron:
case door_gold:
case door_dirt:
@ -472,20 +472,20 @@ namespace MCGalaxy
{
switch (b)
{
case door: return door_air;
case door2: return door2_air;
case door3: return door3_air;
case door4: return door4_air;
case door5: return door5_air;
case door6: return door6_air;
case door7: return door7_air;
case door8: return door8_air;
case door9: return door9_air;
case door10: return door10_air;
case air_switch: return door11_air;
case water_door: return door12_air;
case lava_door: return door13_air;
case air_door: return door14_air;
case door_tree: return door_tree__air;
case door_obsidian: return door_obsidian_air;
case door_glass: return door_glass_air;
case door_stone: return door_stone_air;
case door_leaves: return door_leaves_air;
case door_sand: return door_sand_air;
case door_wood: return door_wood_air;
case door_green: return door_green_air;
case door_tnt: return door_tnt_air;
case door_stair: return door_stair_air;
case air_switch: return air_switch_air;
case water_door: return water_door_air;
case lava_door: return lava_door_air;
case air_door: return air_door_air;
case door_iron: return door_iron_air;
case door_gold: return door_gold_air;
case door_dirt: return door_dirt_air;

83
Levels/IO/FcmFile.cs Normal file
View File

@ -0,0 +1,83 @@
/*
Copyright 2015 MCGalaxy
Dual-licensed under the Educational Community License, Version 2.0 and
the GNU General Public License, Version 3 (the "Licenses"); you may
not use this file except in compliance with the Licenses. You may
obtain a copy of the Licenses at
http://www.opensource.org/licenses/ecl2.php
http://www.gnu.org/licenses/gpl-3.0.html
Unless required by applicable law or agreed to in writing,
software distributed under the Licenses are distributed on an "AS IS"
BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
or implied. See the Licenses for the specific language governing
permissions and limitations under the Licenses.
*/
using System;
using System.IO;
using System.IO.Compression;
using System.Net;
using System.Text;
namespace MCGalaxy.Levels.IO {
public static class FcmFile {
public static Level Load(Stream stream, string name) {
BinaryReader reader = new BinaryReader(stream);
if (reader.ReadInt32() != 0x0FC2AF40 || reader.ReadByte() != 13) {
throw new InvalidDataException( "Unexpected constant in .fcm file" );
}
ushort width = reader.ReadUInt16();
ushort height = reader.ReadUInt16();
ushort length = reader.ReadUInt16();
Level lvl = new Level(name, width, height, length, "full_empty");
lvl.spawnx = (ushort)(reader.ReadInt32() / 32);
lvl.spawny = (ushort)(reader.ReadInt32() / 32);
lvl.spawnz = (ushort)(reader.ReadInt32() / 32);
lvl.rotx = reader.ReadByte();
lvl.roty = reader.ReadByte();
reader.ReadUInt32(); // date modified
reader.ReadUInt32(); // date created
reader.ReadBytes(16); // uuid
reader.ReadBytes(26); // layer index
int metaSize = reader.ReadInt32();
using (DeflateStream ds = new DeflateStream(stream, CompressionMode.Decompress)) {
reader = new BinaryReader(ds);
for (int i = 0; i < metaSize; i++) {
string group = ReadString(reader);
string key = ReadString(reader);
string value = ReadString(reader);
}
int read = ds.Read(lvl.blocks, 0, lvl.blocks.Length);
}
Upgrade(lvl);
lvl.Save(true);
return lvl;
}
static void Upgrade(Level lvl) {
ushort x, y, z;
for (int i = 0; i < lvl.blocks.Length; i++) {
byte block = lvl.blocks[i];
if (block <= Block.CpeMaxBlock) continue;
lvl.blocks[i] = Block.custom_block;
lvl.IntToPos(i, out x, out y, out z);
lvl.SetExtTile(x, y, z, block);
}
}
static string ReadString(BinaryReader reader) {
int length = reader.ReadUInt16();
byte[] data = reader.ReadBytes(length);
return Encoding.ASCII.GetString(data);
}
}
}

View File

@ -510,18 +510,18 @@ namespace MCGalaxy {
case Block.air_flood_down:
case Block.air_flood_up:
blocks[C.b] = 0; break;
case Block.door_air:
case Block.door_tree__air:
//blocks[C.b] = 111;
Blockchange(x, y, z, Block.door); break;
case Block.door2_air:
Blockchange(x, y, z, Block.door_tree); break;
case Block.door_obsidian_air:
//blocks[C.b] = 113;
Blockchange(x, y, z, Block.door2); break;
case Block.door3_air:
Blockchange(x, y, z, Block.door_obsidian); break;
case Block.door_glass_air:
//blocks[C.b] = 114;
Blockchange(x, y, z, Block.door3); break;
case Block.door4_air:
Blockchange(x, y, z, Block.door_glass); break;
case Block.door_stone_air:
//blocks[C.b] = 115;
Blockchange(x, y, z, Block.door4); break;
Blockchange(x, y, z, Block.door_stone); break;
}
try {

View File

@ -29,17 +29,17 @@ namespace MCGalaxy.BlockPhysics {
switch (lvl.blocks[C.b]) {
//Change any door blocks nearby into door_air
case Block.door_air:
case Block.door2_air:
case Block.door3_air:
case Block.door4_air:
case Block.door5_air:
case Block.door6_air:
case Block.door7_air:
case Block.door8_air:
case Block.door10_air:
case Block.door12_air:
case Block.door13_air:
case Block.door_tree__air:
case Block.door_obsidian_air:
case Block.door_glass_air:
case Block.door_stone_air:
case Block.door_leaves_air:
case Block.door_sand_air:
case Block.door_wood_air:
case Block.door_green_air:
case Block.door_stair_air:
case Block.water_door_air:
case Block.lava_door_air:
case Block.door_iron_air:
case Block.door_gold_air:
case Block.door_cobblestone_air:
@ -55,11 +55,11 @@ namespace MCGalaxy.BlockPhysics {
case Block.door_book_air:
AnyDoor(lvl, C, x, y, z, 16);
break;
case Block.door11_air:
case Block.door14_air:
case Block.air_switch_air:
case Block.air_door_air:
AnyDoor(lvl, C, x, y, z, 4, true);
break;
case Block.door9_air:
case Block.door_tnt_air:
AnyDoor(lvl, C, x, y, z, 4);
break;
@ -133,7 +133,7 @@ namespace MCGalaxy.BlockPhysics {
PhysDoor(lvl, x, (ushort)(y - 1), z, instaUpdate);
PhysDoor(lvl, x, (ushort)(y + 1), z, instaUpdate);
if (lvl.blocks[C.b] != Block.door8_air) {
if (lvl.blocks[C.b] != Block.door_green_air) {
CheckDoorRevert(lvl, C, timer);
return;
}

View File

@ -414,6 +414,7 @@
<Compile Include="Levels\Generator\RealisticMapGen.cs" />
<Compile Include="Levels\Generator\TreeGen.cs" />
<Compile Include="Levels\IO\DatFile.cs" />
<Compile Include="Levels\IO\FcmFile.cs" />
<Compile Include="Levels\IO\LvlFile.cs" />
<Compile Include="Levels\IO\LvlProperties.cs" />
<Compile Include="Levels\IO\McfFile.cs" />

View File

@ -742,16 +742,16 @@ namespace MCGalaxy {
}
switch ( b ) {
case Block.door_air: //Door_air
case Block.door2_air:
case Block.door3_air:
case Block.door4_air:
case Block.door5_air:
case Block.door6_air:
case Block.door7_air:
case Block.door8_air:
case Block.door9_air:
case Block.door10_air:
case Block.door_tree__air: //Door_air
case Block.door_obsidian_air:
case Block.door_glass_air:
case Block.door_stone_air:
case Block.door_leaves_air:
case Block.door_sand_air:
case Block.door_wood_air:
case Block.door_green_air:
case Block.door_tnt_air:
case Block.door_stair_air:
case Block.door_iron_air:
case Block.door_gold_air:
case Block.door_cobblestone_air: