/* * Copyright 2013 MovingBlocks * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.terasology.network.internal; import org.terasology.entitySystem.entity.EntityManager; import org.terasology.entitySystem.entity.EntityRef; import org.terasology.logic.common.DisplayNameComponent; import org.terasology.network.Client; import org.terasology.network.ClientComponent; import org.terasology.network.ClientInfoComponent; import org.terasology.network.ColorComponent; import org.terasology.registry.CoreRegistry; import org.terasology.rendering.nui.Color; import java.util.HashSet; import java.util.Set; /** * The common behaviour of all clients - whether local or remote * */ public abstract class AbstractClient implements Client { private EntityRef clientEntity = EntityRef.NULL; @Override public EntityRef getEntity() { return clientEntity; } @Override public void disconnect() { EntityRef clientInfoEntity = clientEntity.getComponent(ClientComponent.class).clientInfo; ClientInfoComponent clientInfoComp = clientInfoEntity.getComponent(ClientInfoComponent.class); clientInfoComp.client = EntityRef.NULL; clientInfoEntity.saveComponent(clientInfoComp); clientEntity.destroy(); } private EntityRef findClientEntityRef() { for (EntityRef entityRef: CoreRegistry.get(EntityManager.class).getEntitiesWith(ClientInfoComponent.class)) { ClientInfoComponent clientInfoComponent = entityRef.getComponent(ClientInfoComponent.class); if (clientInfoComponent.playerId.equals(getId())) { return entityRef; } } return EntityRef.NULL; } protected void createEntity(String preferredName, Color color, EntityManager entityManager) { // Create player entity clientEntity = entityManager.create("engine:client"); // TODO: Send event for clientInfo creation, don't create here. EntityRef clientInfo = findClientEntityRef(); if (!clientInfo.exists()) { clientInfo = createClientInfoEntity(entityManager); } ClientInfoComponent clientInfoComp = clientInfo.getComponent(ClientInfoComponent.class); clientInfoComp.client = clientEntity; clientInfo.saveComponent(clientInfoComp); ClientComponent clientComponent = clientEntity.getComponent(ClientComponent.class); clientComponent.clientInfo = clientInfo; clientEntity.saveComponent(clientComponent); addOrSetColorComponent(clientInfo, color); DisplayNameComponent displayNameComponent = clientInfo.getComponent(DisplayNameComponent.class); if (displayNameComponent == null || !displayNameComponent.name.equals(preferredName)) { String bestAvailableName = findUniquePlayerName(preferredName, entityManager, clientInfo); addOrSetDisplayNameComponent(clientInfo, bestAvailableName); } } private void addOrSetColorComponent(EntityRef clientInfo, Color color) { ColorComponent colorComp = clientInfo.getComponent(ColorComponent.class); if (colorComp != null) { colorComp.color = color; clientInfo.saveComponent(colorComp); } else { colorComp = new ColorComponent(); colorComp.color = color; clientInfo.addComponent(colorComp); } } private void addOrSetDisplayNameComponent(EntityRef clientInfo, String name) { DisplayNameComponent component = clientInfo.getComponent(DisplayNameComponent.class); if (component != null) { component.name = name; clientInfo.saveComponent(component); } else { component = new DisplayNameComponent(); component.name = name; clientInfo.addComponent(component); } } protected String findUniquePlayerName(String preferredName, EntityManager entityManager, EntityRef player) { Set<String> usedNames = findNamesOfOtherPlayers(entityManager, player); String name = preferredName; int nextSuffix = 2; while (usedNames.contains(name)) { name = preferredName + nextSuffix; nextSuffix++; } return name; } private Set<String> findNamesOfOtherPlayers(EntityManager entityManager, EntityRef player) { Set<String> otherNames = new HashSet<>(); for (EntityRef clientInfo: entityManager.getEntitiesWith(ClientInfoComponent.class)) { if (!clientInfo.equals(player)) { DisplayNameComponent displayInfo = clientInfo.getComponent(DisplayNameComponent.class); String usedName = displayInfo.name; otherNames.add(usedName); } } return otherNames; } private EntityRef createClientInfoEntity(EntityManager entityManager) { EntityRef clientInfo; clientInfo = entityManager.create("engine:clientInfo"); // mark clientInfo entities with a dedicated component ClientInfoComponent cic = new ClientInfoComponent(); cic.playerId = getId(); clientInfo.addComponent(cic); return clientInfo; } }