gpt4 book ai didi

java - Red5 - SharedObject 中的 ArrayList 被损坏

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:31:56 28 4
gpt4 key购买 nike

好吧,也许没有损坏。

那么,一些背景知识。我最近将我的 Red5 驱动的游戏从 red5 的 Windows 构建转移到在 Debian Squeeze 上运行的游戏。我有一个游戏大厅,它使用共享对象来维护各种可用游戏的列表。

单个游戏在所述 SharedObject 中存储为 HashMap[String, Object],与它的 game_id 相对应。 HashMap 的几个属性是 ArrayLists,特别是 players(连接的玩家 ID 的 ArrayList[Integer])和 votes(另一个 ArrayList[Integer] 的玩家)提交了投票)

每当我对这些 ArrayList 中的任何一个进行更改时,某处就会出错,我无法再将 HashMap 写入 SharedObject(setAttribute 返回 false)

创建新游戏(服务器端):

HashMap<String, Object> game = new HashMap<String, Object>();
game.put("id", PendingGameManager.GAME_IDX);
game.put("difficulty", difficulty);
game.put("type", type);
game.put("description", this.getDescription(type, difficulty));
game.put("players", new ArrayList<Integer>());
game.put("coords", coords);
game.put("created", Calendar.getInstance().getTimeInMillis());
game.put("votes", new ArrayList<Integer>());
boolean success = this.gamesSO.setAttribute(Integer.toString(PendingGameManager.GAME_IDX), game);

这执行没有问题,成功返回真。

稍后我检索播放器数组并进行修改:

HashMap<String, Object> game = (HashMap<String, Object>)this.gamesSO.getMapAttribute(Integer.toString(game_id));
ArrayList<Integer> players = (ArrayList<Integer>) game.get("players");
players.add(new Integer(Integer.parseInt((user_id))));
boolean success = this.gamesSO.setAttribute(Integer.toString(game_id), game);

这里成功总是返回false。如果为游戏创建一个新的 HashMap 并从旧的 HashMap 复制每个属性但省略 playersvotes 这很好,但无论尝试什么,我都无法得到它维护一个数组。我也用 List 和 Vector 尝试过,结果相同。这是我第一次接触 Java,我一直小心翼翼地只添加 Integer 的类实例,而不是原始 int,但为了我所有的努力,我已经没有想法了。

当它在 Windows 上运行完美时,我最初的实现使用 ArrayList[String] 而不是 ArrayList[Integer]

环境:Debian 压缩版 6.0.6jre 1.7Red5 1.0RC2

如有任何帮助或建议,我们将不胜感激!

最佳答案

根据您的 red5 版本信息,这是方法“setAttribute”的实现:

@Override
public boolean setAttribute(String name, Object value) {
log.debug("setAttribute - name: {} value: {}", name, value);
boolean result = true;
ownerMessage.addEvent(Type.CLIENT_UPDATE_ATTRIBUTE, name, null);
if (value == null && super.removeAttribute(name)) {
// Setting a null value removes the attribute
modified = true;
syncEvents.add(new SharedObjectEvent(Type.CLIENT_DELETE_DATA, name, null));
deleteStats.incrementAndGet();
} else if (value != null && super.setAttribute(name, value)) {
// only sync if the attribute changed
modified = true;
syncEvents.add(new SharedObjectEvent(Type.CLIENT_UPDATE_DATA, name, value));
changeStats.incrementAndGet();
} else {
result = false;
}
notifyModified();
return result;
}

我猜值是 != null(但我可能错了)。但在我看来,它会通过“super.setAttribute”调用将该调用转发给它的父类,这是父类/父类(super class)的实现:

/**
* Set an attribute on this object.
*
* @param name the name of the attribute to change
* @param value the new value of the attribute
* @return true if the attribute value was added or changed, otherwise false
*/
public boolean setAttribute(String name, Object value) {
if (name != null) {
if (value != null) {
// update with new value
Object previous = attributes.put(name, value);
// previous will be null if the attribute didn't exist
return (previous == null || !value.equals(previous));
}
}
return false;
}

这里重要的一行(恕我直言):

return (previous == null || !value.equals(previous));

=> "previous"找不到,然后返回false。

问题是我认为:你正在做的这个转换:

HashMap<String, Object> game = (HashMap<String, Object>)this.gamesSO.getMapAttribute(Integer.toString(game_id));

我不认为“this.gamesSO.getMapAttribute(Integer.toString(game_id));”会返回HashMap,我想我还记得Red5有自己的Map类型。

如果你只是调试并添加一个:

System.out.println(this.gamesSO.getMapAttribute(Integer.toString(game_id)));

和/或添加一些调试断点并验证这是什么类型。然后真的投到这个。

我认为您还应该将 map 指定得更详细。像这样的东西:

 HashMap<String, MyPlayerBean>

然后创建一个 MyPlayerBean 类,其中包含您真正需要的属性。制作这些 Map/List 对象可能有助于快速入门,但如果您的应用程序开始增长,它可能会变得非常难看。

塞巴斯蒂安

关于java - Red5 - SharedObject 中的 ArrayList 被损坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12899224/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com