首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C# (Craft.Net.Client) ServerList异常

C# (Craft.Net.Client) ServerList异常
EN

Stack Overflow用户
提问于 2013-07-29 20:22:04
回答 1查看 511关注 0票数 3

我正在使用Craft.Net.Client库,但是在尝试使用ServerList.SaveTo(字符串文件)方法时出错了:无法在流结束后读取(EndOfStreamException)

ServerList.cs:

代码语言:javascript
复制
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using fNbt;

namespace Craft.Net.Client
{
/// <summary>
/// Provides functionality for interacting with
/// the saved vanilla server list.
/// </summary>
public class ServerList
{
    public static string ServersDat
    {
        get
        {
            return Path.Combine(DotMinecraft.GetDotMinecraftPath(), "servers.dat");
        }
    }

    public ServerList()
    {
        Servers = new List<Server>();
    }

    public List<Server> Servers { get; set; }

    public void Save()
    {
        SaveTo(ServersDat);
    }

    public void SaveTo(string file)
    {
        var nbt = new NbtFile(file); // ERROR : Unable to read beyond the end of the  stream (EndOfStreamException)
        nbt.RootTag = new NbtCompound("");
        var list = new NbtList("servers", NbtTagType.Compound);
        foreach (var server in Servers)
        {
            var compound = new NbtCompound();
            compound.Add(new NbtString("name", server.Name));
            compound.Add(new NbtString("ip", server.Ip));
            compound.Add(new NbtByte("hideAddress", (byte)(server.HideAddress ? 1 : 0)));
            compound.Add(new NbtByte("acceptTextures", (byte)(server.AcceptTextures ? 1 : 0)));
            list.Add(compound);
        }
        nbt.RootTag.Add(list);
        nbt.SaveToFile(file, NbtCompression.None);
    }

    public static ServerList Load()
    {
        return LoadFrom(ServersDat);
    }

    public static ServerList LoadFrom(string file)
    {
        var list = new ServerList();
        var nbt = new NbtFile(file);
        foreach (NbtCompound server in nbt.RootTag["servers"] as NbtList)
        {
            var entry = new Server();
            if (server.Contains("name"))
                entry.Name = server["name"].StringValue;
            if (server.Contains("ip"))
                entry.Ip = server["ip"].StringValue;
            if (server.Contains("hideAddress"))
                entry.HideAddress = server["hideAddress"].ByteValue == 1;
            if (server.Contains("acceptTextures"))
                entry.AcceptTextures = server["acceptTextures"].ByteValue == 1;
            list.Servers.Add(entry);
        }
        return list;
    }

    public class Server
    {
        public string Name { get; set; }
        public string Ip { get; set; }
        public bool HideAddress { get; set; }
        public bool AcceptTextures { get; set; }

        public override string ToString()
        {
            return Name;
        }
    }
}

}

我称之为方法的地方:

代码语言:javascript
复制
ServerList.Server server = new ServerList.Server();
server.Name = "x";
server.Ip = "x";
server.HideAddress = true;
server.AcceptTextures = true;

ServerList list = new ServerList();
list.Servers.Add(server);
if (!File.Exists(RuntimeInfo.getMinecraftDir() + @"\servers.dat"))
{
File.Create(RuntimeInfo.getMinecraftDir() + @"\servers.dat");
}
list.SaveTo(RuntimeInfo.getMinecraftDir() + @"\servers.dat");

我注意到的一件事是,只有当servers.dat为空时才会收到错误,而如果已经保存了服务器,则不会得到错误。

有谁可以帮我?

提前谢谢你,

编辑:多亏了steveg89,下面的解决方案解决了问题(更新SaveTo方法):

代码语言:javascript
复制
    public void SaveTo(string file)
    {
    NbtFile nbt;
    if (File.Exists(RuntimeInfo.getMinecraftDir() + @"\servers.dat"))
    {
        nbt = new NbtFile();
        nbt.SaveToFile(RuntimeInfo.getMinecraftDir() + @"\servers.dat", NbtCompression.None);
    }
    else
        nbt = new NbtFile();

    nbt.RootTag = new NbtCompound("");
    var list = new NbtList("servers", NbtTagType.Compound);
    foreach (var server in Servers)
    {
        var compound = new NbtCompound();
        compound.Add(new NbtString("name", server.Name));
        compound.Add(new NbtString("ip", server.Ip));
        compound.Add(new NbtByte("hideAddress", (byte)(server.HideAddress ? 1 : 0)));
        compound.Add(new NbtByte("acceptTextures", (byte)(server.AcceptTextures ? 1 : 0)));
        list.Add(compound);
    }
    nbt.RootTag.Add(list);
    nbt.SaveToFile(file, NbtCompression.None);           
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-07-29 20:25:55

我注意到他们的NbtFile构造函数试图从文件中读取。它假设文件的格式已经正确。这意味着你必须创建并保存它。他们的API应该为您处理这个问题,但是没有,所以试试下面这个

代码语言:javascript
复制
if (!File.Exists(RuntimeInfo.getMinecraftDir() + @"\servers.dat"))
{
   NbtFile nbt = new NbtFile();
   nbt.SaveToFile(RuntimeInfo.getMinecraftDir() + @"\servers.dat", Nbt.Compression.None);
}

我认为更明智的方法是纠正SaveTo的ServerList方法。这种方法意味着您不必在代码中检查它,但它确实意味着您将使用您自己的Craft.Net风格。我会这样做:

代码语言:javascript
复制
public void SaveTo(string file)
        {
            NbtFile nbt;
            if( File.Exists( file ) )
            {
              nbt = new NbtFile(file);
            }
            else
            {
              nbt = new NbtFile();
            }
            nbt.RootTag = new NbtCompound("");
            var list = new NbtList("servers", NbtTagType.Compound);
            foreach (var server in Servers)
            {
                var compound = new NbtCompound();
                compound.Add(new NbtString("name", server.Name));
                compound.Add(new NbtString("ip", server.Ip));
                compound.Add(new NbtByte("hideAddress", (byte)(server.HideAddress ? 1 : 0)));
                compound.Add(new NbtByte("acceptTextures", (byte)(server.AcceptTextures ? 1 : 0)));
                list.Add(compound);
            }
            nbt.RootTag.Add(list);
            nbt.SaveToFile(file, NbtCompression.None);
        }
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17933470

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档