테스트

aion-server 4.8

Gitteol
최고관리자 · 1 · 💬 0 클론/새로받기
 4.8 61f661d · 1 commits 새로받기(Pull)
game-server/src/com/aionemu/gameserver/services/event/EventService.java
package com.aionemu.gameserver.services.event;

import java.time.LocalDateTime;
import java.time.ZonedDateTime;
import java.util.*;
import java.util.stream.Collectors;

import org.quartz.JobDetail;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.aionemu.commons.services.CronService;
import com.aionemu.gameserver.configs.main.EventsConfig;
import com.aionemu.gameserver.dao.EventDAO;
import com.aionemu.gameserver.dataholders.DataManager;
import com.aionemu.gameserver.model.EventTheme;
import com.aionemu.gameserver.model.gameobjects.Npc;
import com.aionemu.gameserver.model.gameobjects.player.Player;
import com.aionemu.gameserver.model.team.TeamMember;
import com.aionemu.gameserver.model.team.TemporaryPlayerTeam;
import com.aionemu.gameserver.model.templates.event.EventTemplate;
import com.aionemu.gameserver.model.templates.globaldrops.GlobalRule;
import com.aionemu.gameserver.network.aion.serverpackets.SM_VERSION_CHECK;
import com.aionemu.gameserver.skillengine.model.Effect.ForceType;
import com.aionemu.gameserver.utils.PacketSendUtility;
import com.aionemu.gameserver.utils.time.ServerTime;

/**
 * @author Rolandas, Neon
 */
public class EventService {

	private static final Logger log = LoggerFactory.getLogger(EventService.class);

	private volatile JobDetail checkTask = null;
	private volatile Set<Event> activeEvents = Collections.emptySet();
	private volatile List<GlobalRule> activeEventDropRules = Collections.emptyList();
	private volatile Set<Integer> activeEventQuests = Collections.emptySet();
	private volatile Set<ForceType> effectForceTypes = Collections.emptySet();
	private volatile EventTheme eventTheme = EventTheme.NONE;

	private EventService() {
	}

	public boolean start() {
		if (checkTask != null)
			return false;

		validateConfiguredEventNames();
		checkActiveEvents();
		checkTask = CronService.getInstance().schedule(this::onTimeChanged, "0 0/5 * ? * *");
		return true;
	}

	public void stop() {
		if (checkTask != null) {
			CronService.getInstance().cancel(checkTask);
			checkTask = null;
			Set<Event> oldActiveEvents = activeEvents;
			activeEvents = Collections.emptySet();
			activeEventQuests = Collections.emptySet();
			activeEventDropRules = Collections.emptyList();
			updateEventTheme();
			for (Event event : oldActiveEvents) // iterate after emptying activeEvents to ensure correct handling in stop()
				event.stop();
		}
	}

	private void validateConfiguredEventNames() {
		if (!isAllEvents(EventsConfig.DISABLED_EVENTS)) {
			Set<String> eventNames = DataManager.EVENT_DATA.getEvents().stream().map(EventTemplate::getName).collect(Collectors.toSet());
			EventsConfig.DISABLED_EVENTS.forEach(eventName -> {
				if (!eventNames.contains(eventName))
					log.warn("Unknown event \"" + eventName + "\" configured as disabled");
			});
		}
	}

	private void checkActiveEvents() {
		Set<Event> oldActiveEvents = activeEvents;
		Set<Event> newActiveEvents = collectActiveEvents();
		if (!oldActiveEvents.equals(newActiveEvents)) {
			activeEvents = newActiveEvents;
			activeEventQuests = collectQuestIds(activeEvents);
			activeEventDropRules = collectDropRules(activeEvents);
			updateEventTheme();
			startOrStopEvents(oldActiveEvents, activeEvents);
			effectForceTypes = activeEvents.stream().map(Event::getEffectForceType).filter(Objects::nonNull).collect(Collectors.toSet());
		}
	}

	public boolean isInactiveEventForceType(ForceType forceType) {
		return Event.isEventEffectForceType(forceType) && !effectForceTypes.contains(forceType);
	}

	private void onTimeChanged() {
		checkActiveEvents();
		if (!activeEvents.isEmpty()) {
			ZonedDateTime now = ServerTime.now();
			activeEvents.forEach(event -> event.onTimeChanged(now));
		}
	}

	public void onPlayerLogin(Player player) {
		activeEvents.forEach(event -> event.onPlayerLogin(player));
	}

	public void onEnteredTeam(Player player, TemporaryPlayerTeam<? extends TeamMember<Player>> team) {
		activeEvents.forEach(event -> event.onEnteredTeam(player, team));
	}

	public void onLeftTeam(Player player, TemporaryPlayerTeam<? extends TeamMember<Player>> team) {
		activeEvents.forEach(event -> event.onLeftTeam(player, team));
	}

	public void onEnterMap(Player player) {
		activeEvents.forEach(event -> event.onEnterMap(player));
	}

	public void onPveKill(Player killer, Npc victim) {
		activeEvents.forEach(event -> event.onPveKill(killer, victim));
	}

	public void onPvpKill(Player killer, Player victim) {
		activeEvents.forEach(event -> event.onPvpKill(killer, victim));
	}

	private boolean isAllEvents(Set<String> list) {
		return list.size() == 1 && "*".equals(list.iterator().next());
	}

	private Set<Event> collectActiveEvents() {
		if (isAllEvents(EventsConfig.DISABLED_EVENTS))
			return Collections.emptySet();
		LocalDateTime now = ServerTime.now().toLocalDateTime();
		return DataManager.EVENT_DATA.getEvents().stream()
				.filter(et -> !EventsConfig.DISABLED_EVENTS.contains(et.getName()) && et.isInEventPeriod(now))
				.map(this::findOrCreateEvent)
				.collect(Collectors.toSet());
	}

	private Event findOrCreateEvent(EventTemplate et) {
		return activeEvents.stream().filter(event -> et.equals(event.getEventTemplate())).findFirst().orElseGet(() -> new Event(et));
	}

	private void startOrStopEvents(Set<Event> oldActiveEvents, Set<Event> newActiveEvents) {
		for (Event oldActiveEvent : oldActiveEvents) {
			if (!newActiveEvents.contains(oldActiveEvent))
				oldActiveEvent.stop();
		}
		if (!newActiveEvents.isEmpty()) {
			boolean cleanedOldBuffData = false;
			for (Event newActiveEvent : newActiveEvents) {
				if (!oldActiveEvents.contains(newActiveEvent)) {
					if (!cleanedOldBuffData) {
						cleanedOldBuffData = true;
						EventDAO.deleteOldBuffData();
					}
					newActiveEvent.start();
				}
			}
		}
	}

	private Set<Integer> collectQuestIds(Set<Event> events) {
		Set<Integer> questIds = new HashSet<>();
		for (Event event : events) {
			questIds.addAll(event.getEventTemplate().getStartableQuests());
			questIds.addAll(event.getEventTemplate().getMaintainableQuests());
		}
		return questIds;
	}

	private List<GlobalRule> collectDropRules(Set<Event> events) {
		return events.stream().filter(e -> e.getEventTemplate().getEventDropRules() != null)
			.flatMap(e -> e.getEventTemplate().getEventDropRules().stream()).collect(Collectors.toList());
	}

	public Set<Event> getActiveEvents() {
		return activeEvents;
	}

	public boolean isEventActive(String eventName) {
		return activeEvents.stream().anyMatch(e -> e.getEventTemplate().getName().equals(eventName));
	}

	public boolean isActiveEventQuest(int questId) {
		return activeEventQuests.contains(questId);
	}

	public Properties getActiveEventConfigProperties() {
		Properties eventConfigProperties = new Properties();
		activeEvents.stream()
			.map(Event::getEventTemplate)
			.filter(EventTemplate::hasConfigProperties)
			.sorted(Comparator.nullsFirst(Comparator.comparing(EventTemplate::getStartDate)))
			.forEach(et -> {
				try {
					eventConfigProperties.putAll(et.loadConfigProperties());
				} catch (Exception e) {
					log.error("Could not load config properties of event " + et.getName(), e);
				}
			});
		return eventConfigProperties;
	}

	private void updateEventTheme() {
		EventTheme oldEventTheme = eventTheme;
		EventTheme newEventTheme = EventTheme.NONE;
		for (Event event : activeEvents) {
			if (event.getEventTemplate().getTheme() != null) {
				newEventTheme = event.getEventTemplate().getTheme();
				break;
			}
		}
		if (oldEventTheme != newEventTheme) {
			eventTheme = newEventTheme;
			PacketSendUtility.broadcastToWorld(new SM_VERSION_CHECK(eventTheme)); // update city decoration (logged in players see changes after teleport)
		}
	}

	public EventTheme getEventTheme() {
		return eventTheme;
	}

	public List<GlobalRule> getActiveEventDropRules() {
		return activeEventDropRules;
	}

	private static class SingletonHolder {

		protected static final EventService instance = new EventService();
	}

	public static EventService getInstance() {
		return SingletonHolder.instance;
	}
}

📎 첨부파일

댓글 작성 권한이 없습니다.
🏆 포인트 랭킹 TOP 10
순위 닉네임 포인트
1 no_profile 타키야겐지쪽지보내기 자기소개 아이디로 검색 전체게시물 102,949
2 no_profile 동가리쪽지보내기 자기소개 아이디로 검색 전체게시물 63,733
3 no_profile 라프텔쪽지보내기 자기소개 아이디로 검색 전체게시물 51,771
4 no_profile 불멸의행복쪽지보내기 자기소개 아이디로 검색 전체게시물 36,923
5 서번트쪽지보내기 자기소개 아이디로 검색 전체게시물 35,011
6 no_profile 닥터스쪽지보내기 자기소개 아이디로 검색 전체게시물 29,470
7 no_profile 검은고양이쪽지보내기 자기소개 아이디로 검색 전체게시물 29,077
8 no_profile Revolution쪽지보내기 자기소개 아이디로 검색 전체게시물 28,199
9 no_profile 보거스쪽지보내기 자기소개 아이디로 검색 전체게시물 26,731
10 no_profile 호롤롤로쪽지보내기 자기소개 아이디로 검색 전체게시물 17,020
알림 0