Jump to content

Recommended Posts

Posted

A new TvT made by savormix, Bug Less, more options, much better than the old one!

 

Index: config/autoevent.properties
===================================================================
--- config/autoevent.properties	(revision 0)
+++ config/autoevent.properties	(revision 0)
@@ -0,0 +1,104 @@
+# New enhanced engine for automated events
+# No more inefficient class usage, no more useless checks
+# and crap code style made by FBIagent & successors
+# All time values are in milliseconds!
+
+EnableAutoTvT = True
+
+# You may setup as many teams as you wish
+# x1,y1,z1;x2,y2,z2;...
+# Currently = peace zone (monster race track), CHANGE!
+TvTTeamLocations = 12295,182068,-3550;14050,182082,-3555
+# Teleport players to a set location after event instead of where they were
+TvTTeleportAfterEventSpecial = False
+# The special location coordinates (currently: Giran temple entrance)
+TvTTeleportSpecialLocation = 84096,148618,-3404
+
+# You may set up as many reward items as you wish
+# id1,count1;id2,count2;...
+TvTRewards = 57,1000000;5575,100
+# Minimum personal score awarded. TKers or people that keep dying may have a negative score.
+# Everyone starts with 0, if you get a dc and relog, you will have 0.
+# TKers (after relog) will start with (0 - TK points lost) if punish is enabled
+TvTRewardedMinScore = 1
+
+# Maximum level allowed to join
+TvTMaxLevel = 85
+# Minimum level allowed to join
+TvTMinLevel = 1
+# Maximum participants in event
+TvTMaxParticipants = 25
+# Minimum participants in event
+TvTMinParticipants = 6
+# Can players with cw join
+TvTRegisterCursedWeaponOwner = False
+# Can heroes join
+TvTRegisterHero = True
+# If a player logged out and back in during registration period,
+# must he manually register again (false) or he is auto re-registered (true)
+# the player will not be re-registered if slots are full
+TvTRegisterOnRelogin = True
+
+# Initial delay before starting registration once server is loaded up
+TvTDelayInitial = 900000
+# Delay between end of rewards period and new registration period
+TvTDelayBetweenEvents = 900000
+
+# How long shall the registration period last?
+TvTLengthRegistration = 300000
+# How many times should we announce that registration period is in progress?
+# Doesn't include the announcement when the period starts
+TvTAnnounceRegistration = 4
+# How long shall we wait for players to get teleported to the event area
+TvTLengthPreparation = 60000
+# How long shall the event last
+TvTLengthCombat = 240000
+# How long to wait until players are teleported back
+# It works similarly as preparation period;
+# Once the event is over, players get rewarded and instantly teleported
+TvTLengthRewards = 15000
+
+# These items will not be allowed to use and unequiped if necessary
+# The items can be BOTH usable (potions, scrolls) and equipable (weapons, helmets)
+TvTItemsNotAllowed = 6611,6612,6613,6614,6615,6616,6617,6618,6619,6620,6621,9388,9389,9390
+# Same as player spawn protection, but this will override that setting during TvT
+TvTSpawnProtection = 0
+# Remove all effects on start
+TvTCancelBuffsOnStart = False
+# Remove cubics on start
+TvTCancelCubicsOnStart = False
+# Remove servitors on start
+TvTCancelServitorsOnStart = True
+# Remove transformation on start
+TvTCancelTransformationOnStart = False
+# Recover CP/HP/MP
+TvTRecoverOnStart = True
+
+# Use a system that gives rewards for killing and not dying
+TvTGodlikeSystem = True
+# Announce whenever someone acquires godlike status or kills being godlike
+TvTGodlikeAnnounce = True
+# Minimum kills without dying to become godlike
+TvTGodlikeMinKills = 5
+# Points given for each kill while being godlike
+TvTGodlikeKillPoints = 3
+# Static title
+TvTGodlikeTitle = God-like
+
+# Should we punish someone who kills a team member
+TvTPunishTeamKillers = True
+# Reset kill without death count
+TvTPunishTKResetGodlike = True
+# Remove all effects
+TvTPunishTKCancelBuffs = True
+# Points lost per team kill
+TvTPunishTKDecreaseScore = 5
+# Activate effects (CancelBuffs does not affect these)
+TvTPunishTKDebuff = 1201,130;1206,130;1222,130
+
+# Can players see options "To Village" etc AND use them
+TvTReviveSelf = False
+# Recover CP/HP/MP when revived
+TvTReviveRecover = True
+# Maximum time lying dead
+TvTReviveDelay = 10000
Index: src/main/java/com/l2jfree/Config.java
===================================================================
--- src/main/java/com/l2jfree/Config.java	(revision 5950)
+++ src/main/java/com/l2jfree/Config.java	(working copy)
@@ -38,6 +38,9 @@
import org.apache.commons.lang.ArrayUtils;

import com.l2jfree.config.L2Properties;
+import com.l2jfree.gameserver.datatables.SkillTable;
+import com.l2jfree.gameserver.model.L2Skill;
+import com.l2jfree.gameserver.model.entity.events.AutomatedTvT;
import com.l2jfree.gameserver.util.Util;

/**
@@ -51,6 +54,7 @@
	static
	{
		registerConfig(new AltConfig());
+		registerConfig(new AutoEventConfig());
		registerConfig(new BossConfig());
		registerConfig(new CastleConfig());
		registerConfig(new ChampionsConfig());
@@ -3194,6 +3198,157 @@
		}
	}

+	public static boolean AUTO_TVT_ENABLED;
+	public static int[][] AUTO_TVT_TEAM_LOCATIONS;
+	public static boolean AUTO_TVT_OVERRIDE_TELE_BACK;
+	public static int[] AUTO_TVT_DEFAULT_TELE_BACK;
+	public static int AUTO_TVT_REWARD_MIN_POINTS;
+	public static int[] AUTO_TVT_REWARD_IDS;
+	public static int[] AUTO_TVT_REWARD_COUNT;
+	public static int AUTO_TVT_LEVEL_MAX;
+	public static int AUTO_TVT_LEVEL_MIN;
+	public static int AUTO_TVT_PARTICIPANTS_MAX;
+	public static int AUTO_TVT_PARTICIPANTS_MIN;
+	public static long AUTO_TVT_DELAY_INITIAL_REGISTRATION;
+	public static long AUTO_TVT_DELAY_BETWEEN_EVENTS;
+	public static long AUTO_TVT_PERIOD_LENGHT_REGISTRATION;
+	public static long AUTO_TVT_PERIOD_LENGHT_PREPARATION;
+	public static long AUTO_TVT_PERIOD_LENGHT_EVENT;
+	public static long AUTO_TVT_PERIOD_LENGHT_REWARDS;
+	public static int AUTO_TVT_REGISTRATION_ANNOUNCEMENT_COUNT;
+	public static boolean AUTO_TVT_REGISTER_CURSED;
+	public static boolean AUTO_TVT_REGISTER_HERO;
+	public static int[] AUTO_TVT_DISALLOWED_ITEMS;
+	public static boolean AUTO_TVT_REGISTER_AFTER_RELOG;
+	public static boolean AUTO_TVT_START_CANCEL_BUFFS;
+	public static boolean AUTO_TVT_START_CANCEL_CUBICS;
+	public static boolean AUTO_TVT_START_CANCEL_SERVITORS;
+	public static boolean AUTO_TVT_START_CANCEL_TRANSFORMATION;
+	public static boolean AUTO_TVT_START_RECOVER;
+	public static boolean AUTO_TVT_GODLIKE_SYSTEM;
+	public static boolean AUTO_TVT_GODLIKE_ANNOUNCE;
+	public static int AUTO_TVT_GODLIKE_MIN_KILLS;
+	public static int AUTO_TVT_GODLIKE_POINT_MULTIPLIER;
+	public static String AUTO_TVT_GODLIKE_TITLE;
+	public static boolean AUTO_TVT_TK_PUNISH;
+	public static boolean AUTO_TVT_TK_PUNISH_CANCEL;
+	public static boolean AUTO_TVT_TK_RESET_GODLIKE;
+	public static int AUTO_TVT_TK_PUNISH_POINTS_LOST;
+	public static L2Skill[] AUTO_TVT_TK_PUNISH_EFFECTS;
+	public static boolean AUTO_TVT_REVIVE_SELF;
+	public static boolean AUTO_TVT_REVIVE_RECOVER;
+	public static long AUTO_TVT_REVIVE_DELAY;
+	public static int AUTO_TVT_SPAWN_PROTECT;
+
+	private static final class AutoEventConfig extends ConfigLoader
+	{
+		@Override
+		protected String getName()
+		{
+			return "autoevent";
+		}
+
+		@Override
+		protected void loadImpl(Properties properties)
+		{
+			AUTO_TVT_ENABLED = Boolean.parseBoolean(properties.getProperty("EnableAutoTvT", "false"));
+			if (AUTO_TVT_ENABLED)
+				AutomatedTvT.startIfNecessary();
+			StringTokenizer coords;
+			StringTokenizer locations = new StringTokenizer(properties.getProperty("TvTTeamLocations", ""), ";");
+			AUTO_TVT_TEAM_LOCATIONS = new int[locations.countTokens()][3];
+			for (int i = 0; i < AUTO_TVT_TEAM_LOCATIONS.length; i++)
+			{
+				coords = new StringTokenizer(locations.nextToken(), ",");
+				if (coords.countTokens() == 3)
+				{
+					AUTO_TVT_TEAM_LOCATIONS[i] = new int[3];
+					AUTO_TVT_TEAM_LOCATIONS[i][0] = Integer.parseInt(coords.nextToken());
+					AUTO_TVT_TEAM_LOCATIONS[i][1] = Integer.parseInt(coords.nextToken());
+					AUTO_TVT_TEAM_LOCATIONS[i][2] = Integer.parseInt(coords.nextToken());
+				}
+				else
+					AUTO_TVT_TEAM_LOCATIONS[i] = null;
+			}
+			AUTO_TVT_OVERRIDE_TELE_BACK = Boolean.parseBoolean(properties.getProperty("TvTTeleportAfterEventSpecial", "false"));
+			coords = new StringTokenizer(properties.getProperty("TvTTeleportSpecialLocation", ""), ",");
+			if (coords.countTokens() == 3)
+			{
+				AUTO_TVT_DEFAULT_TELE_BACK = new int[3];
+				AUTO_TVT_DEFAULT_TELE_BACK[0] = Integer.parseInt(coords.nextToken());
+				AUTO_TVT_DEFAULT_TELE_BACK[1] = Integer.parseInt(coords.nextToken());
+				AUTO_TVT_DEFAULT_TELE_BACK[2] = Integer.parseInt(coords.nextToken());
+			}
+			else
+				AUTO_TVT_DEFAULT_TELE_BACK = null;
+			AUTO_TVT_REWARD_MIN_POINTS = Integer.parseInt(properties.getProperty("TvTRewardedMinScore", "1"));
+			locations = new StringTokenizer(properties.getProperty("TvTRewards", ""), ";");
+			AUTO_TVT_REWARD_IDS = new int[locations.countTokens()];
+			AUTO_TVT_REWARD_COUNT = new int[locations.countTokens()];
+			for (int i = 0; i < AUTO_TVT_REWARD_IDS.length; i++)
+			{
+				coords = new StringTokenizer(locations.nextToken(), ",");
+				if (coords.countTokens() == 2)
+				{
+					AUTO_TVT_REWARD_IDS[i] = Integer.parseInt(coords.nextToken());
+					AUTO_TVT_REWARD_COUNT[i] = Integer.parseInt(coords.nextToken());
+				}
+				else
+					AUTO_TVT_REWARD_COUNT[i] = 0;
+			}
+			AUTO_TVT_LEVEL_MAX = Integer.parseInt(properties.getProperty("TvTMaxLevel", "85"));
+			AUTO_TVT_LEVEL_MIN = Integer.parseInt(properties.getProperty("TvTMinLevel", "1"));
+			AUTO_TVT_PARTICIPANTS_MAX = Integer.parseInt(properties.getProperty("TvTMaxParticipants", "25"));
+			AUTO_TVT_PARTICIPANTS_MIN = Integer.parseInt(properties.getProperty("TvTMinParticipants", "6"));
+			AUTO_TVT_DELAY_INITIAL_REGISTRATION = Long.parseLong(properties.getProperty("TvTDelayInitial", "900000"));
+			AUTO_TVT_DELAY_BETWEEN_EVENTS = Long.parseLong(properties.getProperty("TvTDelayBetweenEvents", "900000"));
+			AUTO_TVT_PERIOD_LENGHT_REGISTRATION = Long.parseLong(properties.getProperty("TvTLengthRegistration", "300000"));
+			AUTO_TVT_PERIOD_LENGHT_PREPARATION = Long.parseLong(properties.getProperty("TvTLengthPreparation", "50000"));
+			AUTO_TVT_PERIOD_LENGHT_EVENT = Long.parseLong(properties.getProperty("TvTLengthCombat", "240000"));
+			AUTO_TVT_PERIOD_LENGHT_REWARDS = Long.parseLong(properties.getProperty("TvTLengthRewards", "15000"));
+			AUTO_TVT_REGISTRATION_ANNOUNCEMENT_COUNT = Integer.parseInt(properties.getProperty("TvTAnnounceRegistration", "3"));
+			AUTO_TVT_REGISTER_CURSED = Boolean.parseBoolean(properties.getProperty("TvTRegisterCursedWeaponOwner", "false"));
+			AUTO_TVT_REGISTER_HERO = Boolean.parseBoolean(properties.getProperty("TvTRegisterHero", "true"));
+			coords = new StringTokenizer(properties.getProperty("TvTItemsNotAllowed", ""), ",");
+			AUTO_TVT_DISALLOWED_ITEMS = new int[coords.countTokens()];
+			for (int i = 0; i < AUTO_TVT_DISALLOWED_ITEMS.length; i++)
+				AUTO_TVT_DISALLOWED_ITEMS[i] = Integer.parseInt(coords.nextToken());
+			AUTO_TVT_REGISTER_AFTER_RELOG = Boolean.parseBoolean(properties.getProperty("TvTRegisterOnRelogin", "true"));
+			AUTO_TVT_START_CANCEL_BUFFS = Boolean.parseBoolean(properties.getProperty("TvTCancelBuffsOnStart", "false"));
+			AUTO_TVT_START_CANCEL_CUBICS = Boolean.parseBoolean(properties.getProperty("TvTCancelCubicsOnStart", "false"));
+			AUTO_TVT_START_CANCEL_SERVITORS = Boolean.parseBoolean(properties.getProperty("TvTCancelServitorsOnStart", "true"));
+			AUTO_TVT_START_CANCEL_TRANSFORMATION = Boolean.parseBoolean(properties.getProperty("TvTCancelTransformationOnStart", "true"));
+			AUTO_TVT_START_RECOVER = Boolean.parseBoolean(properties.getProperty("TvTRecoverOnStart", "true"));
+			AUTO_TVT_GODLIKE_SYSTEM = Boolean.parseBoolean(properties.getProperty("TvTGodlikeSystem", "true"));
+			AUTO_TVT_GODLIKE_ANNOUNCE = Boolean.parseBoolean(properties.getProperty("TvTGodlikeAnnounce", "true"));
+			AUTO_TVT_GODLIKE_MIN_KILLS = Integer.parseInt(properties.getProperty("TvTGodlikeMinKills", "5"));
+			AUTO_TVT_GODLIKE_POINT_MULTIPLIER = Integer.parseInt(properties.getProperty("TvTGodlikeKillPoints", "3"));
+			AUTO_TVT_GODLIKE_TITLE = properties.getProperty("TvTGodlikeTitle", "God-like").trim();
+			AUTO_TVT_TK_PUNISH = Boolean.parseBoolean(properties.getProperty("TvTPunishTeamKillers", "true"));
+			AUTO_TVT_TK_PUNISH_CANCEL = Boolean.parseBoolean(properties.getProperty("TvTPunishTKCancelBuffs", "true"));
+			AUTO_TVT_TK_RESET_GODLIKE = Boolean.parseBoolean(properties.getProperty("TvTPunishTKResetGodlike", "true"));
+			AUTO_TVT_TK_PUNISH_POINTS_LOST = Integer.parseInt(properties.getProperty("TvTPunishTKDecreaseScore", "5"));
+			locations = new StringTokenizer(properties.getProperty("TvTPunishTKDebuff", ""), ";");
+			AUTO_TVT_TK_PUNISH_EFFECTS = new L2Skill[locations.countTokens()];
+			for (int i = 0; i < AUTO_TVT_TK_PUNISH_EFFECTS.length; i++)
+			{
+				coords = new StringTokenizer(locations.nextToken(), ",");
+				if (coords.countTokens() == 2)
+				{
+					AUTO_TVT_TK_PUNISH_EFFECTS[i] = SkillTable.getInstance().getInfo(
+							Integer.parseInt(coords.nextToken()),
+							Integer.parseInt(coords.nextToken()));
+				}
+				else
+					AUTO_TVT_TK_PUNISH_EFFECTS[i] = null;
+			}
+			AUTO_TVT_REVIVE_SELF = Boolean.parseBoolean(properties.getProperty("TvTReviveSelf", "false"));
+			AUTO_TVT_REVIVE_RECOVER = Boolean.parseBoolean(properties.getProperty("TvTReviveRecover", "true"));
+			AUTO_TVT_REVIVE_DELAY = Long.parseLong(properties.getProperty("TvTReviveDelay", "5000"));
+			AUTO_TVT_SPAWN_PROTECT = Integer.parseInt(properties.getProperty("TvTSpawnProtection", "0"));
+		}
+	}
+
	// *******************************************************************************************

	public static class ClassMasterSettings
Index: src/main/java/com/l2jfree/gameserver/GameServer.java
===================================================================
--- src/main/java/com/l2jfree/gameserver/GameServer.java	(revision 5950)
+++ src/main/java/com/l2jfree/gameserver/GameServer.java	(working copy)
@@ -122,6 +122,7 @@
import com.l2jfree.gameserver.model.L2World;
import com.l2jfree.gameserver.model.entity.Castle;
import com.l2jfree.gameserver.model.entity.Hero;
+import com.l2jfree.gameserver.model.entity.events.AutomatedTvT;
import com.l2jfree.gameserver.model.olympiad.Olympiad;
import com.l2jfree.gameserver.model.restriction.ObjectRestrictions;
import com.l2jfree.gameserver.network.IOFloodManager;
@@ -392,6 +393,7 @@
		{
			_log.warn("DynamicExtension could not be loaded and initialized", ex);
		}
+		AutomatedTvT.getInstance();

		Util.printSection("Handlers");
		ItemHandler.getInstance();
Index: src/main/java/com/l2jfree/gameserver/handler/VoicedCommandHandler.java
===================================================================
--- src/main/java/com/l2jfree/gameserver/handler/VoicedCommandHandler.java	(revision 5950)
+++ src/main/java/com/l2jfree/gameserver/handler/VoicedCommandHandler.java	(working copy)
@@ -18,6 +18,7 @@
import com.l2jfree.gameserver.handler.voicedcommandhandlers.Banking;
import com.l2jfree.gameserver.handler.voicedcommandhandlers.CastleDoors;
import com.l2jfree.gameserver.handler.voicedcommandhandlers.Hellbound;
+import com.l2jfree.gameserver.handler.voicedcommandhandlers.JoinEvent;
import com.l2jfree.gameserver.handler.voicedcommandhandlers.VersionInfo;
import com.l2jfree.gameserver.handler.voicedcommandhandlers.Wedding;
import com.l2jfree.util.HandlerRegistry;
@@ -40,6 +41,7 @@
			registerVoicedCommandHandler(new Banking());
		registerVoicedCommandHandler(new CastleDoors());
		registerVoicedCommandHandler(new Hellbound());
+		registerVoicedCommandHandler(new JoinEvent());
		registerVoicedCommandHandler(new VersionInfo());
		if (Config.ALLOW_WEDDING)
			registerVoicedCommandHandler(new Wedding());
Index: src/main/java/com/l2jfree/gameserver/handler/voicedcommandhandlers/JoinEvent.java
===================================================================
--- src/main/java/com/l2jfree/gameserver/handler/voicedcommandhandlers/JoinEvent.java	(revision 0)
+++ src/main/java/com/l2jfree/gameserver/handler/voicedcommandhandlers/JoinEvent.java	(revision 0)
@@ -0,0 +1,39 @@
+package com.l2jfree.gameserver.handler.voicedcommandhandlers;
+
+import com.l2jfree.gameserver.handler.IVoicedCommandHandler;
+import com.l2jfree.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jfree.gameserver.model.entity.events.AutomatedTvT;
+
+/**
+ * @author savormix
+ *
+ */
+public class JoinEvent implements IVoicedCommandHandler
+{
+	private static final String[] CMDS = {
+		"jointvt", "joinTvT", "joinTvt"
+	};
+
+	/* (non-Javadoc)
+	 * @see com.l2jfree.gameserver.handler.IVoicedCommandHandler#useVoicedCommand(java.lang.String, com.l2jfree.gameserver.model.actor.instance.L2PcInstance, java.lang.String)
+	 */
+	@Override
+	public boolean useVoicedCommand(String command, L2PcInstance activeChar, String target)
+	{
+		if (command.equalsIgnoreCase(CMDS[0]))
+		{
+			AutomatedTvT.getInstance().registerPlayer(activeChar);
+			return true;
+		}
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.l2jfree.gameserver.handler.IVoicedCommandHandler#getVoicedCommandList()
+	 */
+	@Override
+	public String[] getVoicedCommandList()
+	{
+		return CMDS;
+	}
+}

Posted

Continuing...

Index: src/main/java/com/l2jfree/gameserver/model/actor/L2Character.java
===================================================================
--- src/main/java/com/l2jfree/gameserver/model/actor/L2Character.java	(revision 5950)
+++ src/main/java/com/l2jfree/gameserver/model/actor/L2Character.java	(working copy)
@@ -75,6 +75,7 @@
import com.l2jfree.gameserver.model.actor.shot.CharShots;
import com.l2jfree.gameserver.model.actor.stat.CharStat;
import com.l2jfree.gameserver.model.actor.status.CharStatus;
+import com.l2jfree.gameserver.model.entity.events.AutomatedTvT;
import com.l2jfree.gameserver.model.itemcontainer.Inventory;
import com.l2jfree.gameserver.model.mapregion.TeleportWhereType;
import com.l2jfree.gameserver.model.quest.Quest;
@@ -2291,7 +2292,7 @@
				((L2Playable) this).stopPhoenixBlessing(true);
			}

-			if(restorefull)
+			if (restorefull)
			{
				//_status.setCurrentCp(getMaxCp()); //this is not confirmed...
				_status.setCurrentHp(getMaxHp()); //confirmed
@@ -2304,6 +2305,9 @@
				//_status.setCurrentMp(getMaxMp() * Config.RESPAWN_RESTORE_MP);
			}

+			if (this instanceof L2PcInstance)
+				AutomatedTvT.getInstance().recover((L2PcInstance) this);
+
			// Start broadcast status
			broadcastPacket(new Revive(this));

@@ -5548,6 +5552,9 @@
		if (attackerPlayer.isInFunEvent() && targetPlayer.isInFunEvent())
			return false;

+		if (AutomatedTvT.isPlaying(attackerPlayer) && AutomatedTvT.isPlaying(targetPlayer))
+			return false;
+		
		if (attackerPlayer.getAccessLevel() >= Config.GM_PEACEATTACK)
			return false;

Index: src/main/java/com/l2jfree/gameserver/model/actor/instance/L2PcInstance.java
===================================================================
--- src/main/java/com/l2jfree/gameserver/model/actor/instance/L2PcInstance.java	(revision 5950)
+++ src/main/java/com/l2jfree/gameserver/model/actor/instance/L2PcInstance.java	(working copy)
@@ -150,6 +150,7 @@
import com.l2jfree.gameserver.model.entity.GrandBossState;
import com.l2jfree.gameserver.model.entity.L2Event;
import com.l2jfree.gameserver.model.entity.Siege;
+import com.l2jfree.gameserver.model.entity.events.AutomatedTvT;
import com.l2jfree.gameserver.model.entity.events.CTF;
import com.l2jfree.gameserver.model.entity.events.DM;
import com.l2jfree.gameserver.model.entity.events.TvT;
@@ -3371,12 +3372,16 @@
	 */
	public void setProtection(boolean protect)
	{
+		int proTime = AutomatedTvT.isPlaying(this) ? Config.AUTO_TVT_SPAWN_PROTECT : Config.PLAYER_SPAWN_PROTECTION;
+		if (protect && (proTime == 0 || isInOlympiadMode()))
+			return;
+
		if (_log.isDebugEnabled() && (protect || _protectEndTime > 0))
			_log.debug(getName() + ": Protection "
-					+ (protect ? "ON " + (GameTimeController.getGameTicks() + Config.PLAYER_SPAWN_PROTECTION * GameTimeController.TICKS_PER_SECOND) : "OFF")
+					+ (protect ? "ON " + (GameTimeController.getGameTicks() + proTime * GameTimeController.TICKS_PER_SECOND) : "OFF")
					+ " (currently " + GameTimeController.getGameTicks() + ")");

-		_protectEndTime = protect ? GameTimeController.getGameTicks() + Config.PLAYER_SPAWN_PROTECTION * GameTimeController.TICKS_PER_SECOND : 0;
+		_protectEndTime = protect ? GameTimeController.getGameTicks() + proTime * GameTimeController.TICKS_PER_SECOND : 0;
	}

	public long getProtection()
@@ -4470,6 +4475,12 @@
				}
			}

+			if (AutomatedTvT.isPlaying(this) && AutomatedTvT.isPlaying(pk))
+			{
+				srcInPvP = true;
+				AutomatedTvT.getInstance().onKill(pk, this);
+			}
+
			if (!srcInPvP)
			{
				if (pk == null || !pk.isCursedWeaponEquipped())
@@ -4748,6 +4759,9 @@
		if (isInsideZone(L2Zone.FLAG_PVP))
			return;

+		if (AutomatedTvT.isPlaying(this) && AutomatedTvT.isPlaying(targetPlayer))
+			return;
+
		// Check if it's pvp
		if ((checkIfPvP(target) && //  Can pvp and
				targetPlayer.getPvpFlag() != 0 // Target player has pvp flag set
@@ -4948,6 +4962,8 @@
		if ((TvT._started && _inEventTvT && player_target._inEventTvT) || (DM._started && _inEventDM && player_target._inEventDM)
				|| (CTF._started && _inEventCTF && player_target._inEventCTF) || (_inEventVIP && VIP._started && player_target._inEventVIP))
			return;
+		if (AutomatedTvT.isPlaying(this) && AutomatedTvT.isPlaying(player_target))
+			return;

		if ((isInDuel() && player_target.getDuelId() == getDuelId()))
			return;
@@ -7695,6 +7711,10 @@
		if (isCursedWeaponEquipped())
			return true;

+		if (AutomatedTvT.isPlaying(this) &&
+				AutomatedTvT.isPlaying((L2PcInstance) attacker))
+			return true;
+
		// Check if the attacker is in olympia and olympia start
		if (attacker instanceof L2PcInstance && ((L2PcInstance) attacker).isInOlympiadMode())
		{
@@ -8469,6 +8489,8 @@
		)
		{
			L2PcInstance target = (L2PcInstance) obj;
+			if (AutomatedTvT.isPlaying(this) && AutomatedTvT.isPlaying(target))
+				return true;
			if (skill.isPvpSkill()) // Pvp skill
			{
				if (getClan() != null && target.getClan() != null)
@@ -10722,8 +10744,7 @@

		getKnownList().updateKnownObjects();

-		if ((Config.PLAYER_SPAWN_PROTECTION > 0) && !isInOlympiadMode())
-			setProtection(true);
+		setProtection(true);

		// Trained beast is after teleport lost
		if (getTrainedBeast() != null)
@@ -11083,6 +11104,7 @@

		abortCast();
		abortAttack();
+		AutomatedTvT.getInstance().onDisconnection(this);

		try
		{
@@ -14008,10 +14030,50 @@
			sendMessage("You can't teleport during Observation Mode.");
			return false;
		}
+
+		if (AutomatedTvT.isPlaying(this))
+		{
+			sendPacket(SystemMessageId.NOT_WORKING_PLEASE_TRY_AGAIN_LATER);
+			return false;
+		}

		return true;
	}

+	private int killsWithoutDeath = 0;
+	private int points = 0;
+	private int team = -1;
+
+	public final int getKillsWithoutDeath()
+	{
+		return killsWithoutDeath;
+	}
+
+	public final void setKillsWithoutDeath(int val)
+	{
+		killsWithoutDeath = val;
+	}
+
+	public final int getEventPoints()
+	{
+		return points;
+	}
+
+	public final void setEventPoints(int val)
+	{
+		points = val;
+	}
+
+	public final int getEventTeam()
+	{
+		return team;
+	}
+
+	public final void setEventTeam(int val)
+	{
+		team = val;
+	}
+
	public boolean canSee(L2Character cha)
	{
		if (isGM())

Posted

Those big codes sucks T_T

Index: src/main/java/com/l2jfree/gameserver/model/entity/events/AutomatedTvT.java
===================================================================
--- src/main/java/com/l2jfree/gameserver/model/entity/events/AutomatedTvT.java	(revision 0)
+++ src/main/java/com/l2jfree/gameserver/model/entity/events/AutomatedTvT.java	(revision 0)
@@ -0,0 +1,706 @@
+package com.l2jfree.gameserver.model.entity.events;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.util.concurrent.ScheduledFuture;
+
+import javolution.util.FastList;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.l2jfree.Config;
+import com.l2jfree.L2DatabaseFactory;
+import com.l2jfree.gameserver.Announcements;
+import com.l2jfree.gameserver.ThreadPoolManager;
+import com.l2jfree.gameserver.model.L2ItemInstance;
+import com.l2jfree.gameserver.model.L2Skill;
+import com.l2jfree.gameserver.model.Location;
+import com.l2jfree.gameserver.model.actor.instance.L2CubicInstance;
+import com.l2jfree.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jfree.gameserver.model.olympiad.Olympiad;
+import com.l2jfree.gameserver.model.zone.L2Zone;
+import com.l2jfree.gameserver.network.SystemChatChannelId;
+import com.l2jfree.gameserver.network.SystemMessageId;
+import com.l2jfree.gameserver.network.serverpackets.CreatureSay;
+import com.l2jfree.gameserver.network.serverpackets.SystemMessage;
+import com.l2jfree.gameserver.util.Broadcast;
+import com.l2jfree.tools.random.Rnd;
+
+/**
+ * @author savormix
+ */
+public final class AutomatedTvT
+{
+	private static final Log _log = LogFactory.getLog(AutomatedTvT.class);
+	private static final String REMOVE_DISCONNECTED_PLAYER = "UPDATE characters SET heading=?,x=?,y=?,z=?,title=? WHERE charId=?";
+	private static final String evtName = "Team versus team";
+
+	//when the event has ended and not yet started
+	private static final int STATUS_NOT_IN_PROGRESS	= 0;
+	//registration in progress
+	private static final int STATUS_REGISTRATION	= 1;
+	//registration ended, players frozen & teled to the place, waiting for them to appear
+	private static final int STATUS_PREPARATION		= 2;
+	//players are allowed to fight
+	private static final int STATUS_COMBAT			= 3;
+	//players are frozen, rewarded and teled back to where they were
+	private static final int STATUS_REWARDS			= 4;
+
+	private static AutomatedTvT instance = null;
+
+	public static final AutomatedTvT getInstance()
+	{
+		if (instance == null)
+			instance = new AutomatedTvT();
+		return instance;
+	}
+
+	/**
+	 * Called when configuration is reloaded and {@link Config#AUTO_TVT_ENABLED} = true<BR>
+	 * <CODE>instance</CODE> will only be <CODE>null</CODE> when the config is loaded during
+	 * server startup, and we don't want the event to start countdown THAT early.<BR>
+	 * <I>Normally initialization is called when loading [static] extensions.</I>
+	 */
+	public static final void startIfNecessary()
+	{
+		if (instance != null && !instance.active)
+			instance.tpm.scheduleGeneral(instance.task, Config.AUTO_TVT_DELAY_INITIAL_REGISTRATION);
+	}
+
+	private final ThreadPoolManager tpm;
+
+	private final AutoEventTask task;
+	private final AutoReviveTask taskDuring;
+	private ScheduledFuture<?> reviver;
+	private ScheduledFuture<?> event;
+
+	private final FastList<Integer> registered;
+	private final FastList<L2PcInstance> participants;
+	private int[] partOIDs = null;
+	private int[] partTeams = null;
+	private Location[] partLocs = null;
+	private String[] partTitles = null;
+	private int[] partColors = null;
+	private L2PcInstance[] part = null;
+	private boolean[] partTKs = null;
+
+	private int status;
+	private boolean active;
+	private int announced;
+
+	private int[] teamPts = null;
+	private int[] teamCR = null;
+	private int[] teamCG = null;
+	private int[] teamCB = null;
+
+	private AutomatedTvT()
+	{
+		tpm = ThreadPoolManager.getInstance();
+		status = STATUS_NOT_IN_PROGRESS;
+		announced = 0;
+		participants = new FastList<L2PcInstance>(10);
+		registered = new FastList<Integer>(10);
+		task = new AutoEventTask();
+		taskDuring = new AutoReviveTask();
+		reviver = null;
+		active = Config.AUTO_TVT_ENABLED;
+		if (active)
+			tpm.scheduleGeneral(task, Config.AUTO_TVT_DELAY_INITIAL_REGISTRATION);
+		_log.info("AutomatedTvT: initialized.");
+	}
+
+	private class AutoEventTask implements Runnable
+	{
+		@Override
+		public void run()
+		{
+			switch (status)
+			{
+			case STATUS_NOT_IN_PROGRESS:
+				if (Config.AUTO_TVT_ENABLED)
+					registrationStart();
+				else
+					active = false;
+				break;
+			case STATUS_REGISTRATION:
+				if (announced < (Config.AUTO_TVT_REGISTRATION_ANNOUNCEMENT_COUNT + 2))
+					registrationAnnounce();
+				else
+					registrationEnd();
+				break;
+			case STATUS_PREPARATION:
+				eventStart();
+				break;
+			case STATUS_COMBAT:
+				eventEnd();
+				break;
+			case STATUS_REWARDS:
+				status = STATUS_NOT_IN_PROGRESS;
+				tpm.scheduleGeneral(task, Config.AUTO_TVT_DELAY_BETWEEN_EVENTS);
+				break;
+			default:
+				_log.fatal("Incorrect status set in Automated " + evtName + ", terminating the event!");
+			}
+		}
+	}
+
+	private class AutoReviveTask implements Runnable
+	{
+		@Override
+		public void run()
+		{
+			if (part == null)
+				return;
+			for (L2PcInstance p : part)
+				if (p != null && p.isDead())
+					revive(p);
+		}
+	}
+
+	private final void registrationStart()
+	{
+		status = STATUS_REGISTRATION;
+		Announcements.getInstance().announceToAll(SystemMessageId.REGISTRATION_PERIOD);
+		SystemMessage time = new SystemMessage(SystemMessageId.REGISTRATION_TIME_S1_S2_S3);
+		long timeLeft = Config.AUTO_TVT_PERIOD_LENGHT_REGISTRATION / 1000;
+		time.addNumber(timeLeft / 3600);
+		time.addNumber(timeLeft % 3600 / 60);
+		time.addNumber(timeLeft % 3600 % 60);
+		Broadcast.toAllOnlinePlayers(time);
+		Announcements.getInstance().announceToAll("To join the " + evtName + " you must type .jointvt");
+		tpm.scheduleGeneral(task, Config.AUTO_TVT_PERIOD_LENGHT_REGISTRATION / (Config.AUTO_TVT_REGISTRATION_ANNOUNCEMENT_COUNT + 2));
+	}
+
+	private final void registrationAnnounce()
+	{
+		SystemMessage time = new SystemMessage(SystemMessageId.REGISTRATION_TIME_S1_S2_S3);
+		long timeLeft = Config.AUTO_TVT_PERIOD_LENGHT_REGISTRATION;
+		long elapsed = timeLeft / (Config.AUTO_TVT_REGISTRATION_ANNOUNCEMENT_COUNT + 2) * announced;
+		timeLeft -= elapsed;
+		timeLeft /= 1000;
+		time.addNumber(timeLeft / 3600);
+		time.addNumber(timeLeft % 3600 / 60);
+		time.addNumber(timeLeft % 3600 % 60);
+		Broadcast.toAllOnlinePlayers(time);
+		Announcements.getInstance().announceToAll("To join the " + evtName + " you must type .jointvt");
+		announced++;
+		tpm.scheduleGeneral(task, Config.AUTO_TVT_PERIOD_LENGHT_REGISTRATION / (Config.AUTO_TVT_REGISTRATION_ANNOUNCEMENT_COUNT + 2));
+	}
+
+	private final void registrationEnd()
+	{
+		announced = 0;
+		status = STATUS_PREPARATION;
+
+		registered.clear();
+
+		L2PcInstance[] reged = participants.toArray(new L2PcInstance[participants.size()]);
+		for (L2PcInstance player : reged)
+		{
+			if (!canJoin(player))
+			{
+				player.sendMessage("You no longer meet the requirements to join " + evtName);
+				participants.remove(player);
+			}
+		}
+		reged = null;
+
+		if (participants.size() < Config.AUTO_TVT_PARTICIPANTS_MIN)
+		{
+			Announcements.getInstance().announceToAll(evtName + " will not start, not enough players!");
+			participants.clear();
+			status = STATUS_NOT_IN_PROGRESS;
+			tpm.scheduleGeneral(task, Config.AUTO_TVT_DELAY_BETWEEN_EVENTS);
+			return;
+		}
+
+		teamPts = new int[Config.AUTO_TVT_TEAM_LOCATIONS.length];
+		teamCR = new int[Config.AUTO_TVT_TEAM_LOCATIONS.length];
+		teamCG = new int[Config.AUTO_TVT_TEAM_LOCATIONS.length];
+		teamCB = new int[Config.AUTO_TVT_TEAM_LOCATIONS.length];
+		int[] temp;
+		for (int i = 0; i < teamPts.length; i++)
+		{
+			teamPts[i] = 0;
+			temp = correctColor(teamCR, teamCG, teamCB,
+					Rnd.get(256), Rnd.get(256), Rnd.get(256), i);
+			teamCR[i] = temp[0];
+			teamCG[i] = temp[1];
+			teamCB[i] = temp[2];
+		}
+
+		int currTeam = 0;
+		part = participants.toArray(new L2PcInstance[participants.size()]);
+		participants.clear();
+		partOIDs = new int[part.length];
+		partTeams = new int[partOIDs.length];
+		partLocs = new Location[partOIDs.length];
+		partTitles = new String[partOIDs.length];
+		partColors = new int[partOIDs.length];
+		partTKs = new boolean[partOIDs.length];
+		SystemMessage time = new SystemMessage(SystemMessageId.BATTLE_BEGINS_S1_S2_S3);
+		long timeLeft = Config.AUTO_TVT_PERIOD_LENGHT_PREPARATION / 1000;
+		time.addNumber(timeLeft / 3600);
+		time.addNumber(timeLeft % 3600 / 60);
+		time.addNumber(timeLeft % 3600 % 60);
+		for (int i = 0; i < partOIDs.length; i++)
+		{
+			L2PcInstance player = part[i]; 
+			partOIDs[i] = player.getObjectId();
+			partTeams[i] = currTeam;
+			player.setEventTeam(currTeam);
+			partLocs[i] = player.getLoc();
+			partTitles[i] = player.getTitle();
+			partColors[i] = player.getAppearance().getNameColor();
+			player.getAppearance().setNameColor((teamCR[currTeam] & 0xFF) +
+					(teamCG[currTeam] << 8) + (teamCB[currTeam] << 16));
+			partTKs[i] = false;
+			player.setIsPetrified(true);
+			player.sendPacket(time);
+			checkEquipment(player);
+			if (Config.AUTO_TVT_START_CANCEL_BUFFS)
+				player.stopAllEffects();
+			if (Config.AUTO_TVT_START_CANCEL_CUBICS && !player.getCubics().isEmpty())
+			{
+				for (L2CubicInstance cubic : player.getCubics().values())
+				{
+					cubic.stopAction();
+					cubic.cancelDisappear();
+				}
+				player.getCubics().clear();
+			}
+			if (Config.AUTO_TVT_START_CANCEL_SERVITORS && player.getPet() != null)
+				player.getPet().unSummon();
+			if (Config.AUTO_TVT_START_CANCEL_TRANSFORMATION && player.isTransformed())
+				player.untransform();
+			if (player.isDead())
+				player.setIsPendingRevive(true);
+			player.teleToLocation(Config.AUTO_TVT_TEAM_LOCATIONS[currTeam][0],
+					Config.AUTO_TVT_TEAM_LOCATIONS[currTeam][1],
+					Config.AUTO_TVT_TEAM_LOCATIONS[currTeam][2]);
+			if (Config.AUTO_TVT_START_RECOVER)
+			{
+				player.getStatus().setCurrentCp(player.getMaxCp());
+				player.getStatus().setCurrentHpMp(player.getMaxHp(), player.getMaxMp());
+			}
+			currTeam++;
+			if (currTeam == teamPts.length)
+				currTeam = 0;
+		}
+		tpm.scheduleGeneral(task, Config.AUTO_TVT_PERIOD_LENGHT_PREPARATION);
+	}
+
+	private final void eventStart()
+	{
+		status = STATUS_COMBAT;
+		SystemMessage time = new SystemMessage(SystemMessageId.BATTLE_ENDS_S1_S2_S3);
+		long timeLeft = Config.AUTO_TVT_PERIOD_LENGHT_EVENT / 1000;
+		time.addNumber(timeLeft / 3600);
+		time.addNumber(timeLeft % 3600 / 60);
+		time.addNumber(timeLeft % 3600 % 60);
+		for (int i = 0; i < partOIDs.length; i++)
+		{
+			L2PcInstance player = part[i];
+			player.setIsPetrified(false);
+			player.sendPacket(time);
+			updatePlayerTitle(player, false);
+		}
+		reviver = tpm.scheduleAtFixedRate(taskDuring, Config.AUTO_TVT_REVIVE_DELAY, Config.AUTO_TVT_REVIVE_DELAY);
+		event = tpm.scheduleGeneral(task, Config.AUTO_TVT_PERIOD_LENGHT_EVENT);
+	}
+
+	private final void eventEnd()
+	{
+		if (status != STATUS_COMBAT)
+			return;
+		status = STATUS_REWARDS;
+		reviver.cancel(true);
+		if (!event.cancel(false))
+			return;
+		int winnerTeam = getWinnerTeam();
+
+		if (winnerTeam != -1)
+		{
+			Announcements.getInstance().announceToAll(evtName + ": Team " +
+					(winnerTeam + 1) + "wins!");
+			Announcements.getInstance().announceToAll(evtName + ": Cumulative score: " +
+					teamPts[winnerTeam]);
+		}
+		else
+			Announcements.getInstance().announceToAll(evtName + ": There is no winner team.");
+
+		for (int i = 0; i < part.length; i++)
+		{
+			if (part[i] == null)
+			{
+				removeDisconnected(partOIDs[i], partLocs[i], partTitles[i]);
+				continue;
+			}
+
+			if (part[i].getEventTeam() == winnerTeam &&
+					part[i].getEventPoints() >= Config.AUTO_TVT_REWARD_MIN_POINTS)
+				reward(part[i]);
+
+			part[i].setTitle(partTitles[i]);
+			part[i].getAppearance().setNameColor(partColors[i]);
+			part[i].setEventPoints(0);
+			part[i].setEventTeam(-1);
+			if (part[i].isDead())
+				part[i].setIsPendingRevive(true);
+
+			if (Config.AUTO_TVT_OVERRIDE_TELE_BACK)
+				part[i].teleToLocation(Config.AUTO_TVT_DEFAULT_TELE_BACK[0],
+						Config.AUTO_TVT_DEFAULT_TELE_BACK[1],
+						Config.AUTO_TVT_DEFAULT_TELE_BACK[2]);
+			else
+				part[i].teleToLocation(partLocs[i], true);
+			part[i].getStatus().setCurrentCp(part[i].getMaxCp());
+			part[i].getStatus().setCurrentHpMp(part[i].getMaxHp(), part[i].getMaxMp());
+		}
+		tpm.scheduleGeneral(task, Config.AUTO_TVT_PERIOD_LENGHT_REWARDS);
+	}
+

 

NOTE!!! This same part continue in the next reply!

Posted

+	public final void addDisconnected(L2PcInstance participant)
+	{
+		switch (status)
+		{
+		case STATUS_REGISTRATION:
+			if (Config.AUTO_TVT_REGISTER_AFTER_RELOG &&
+					registered.remove(participant.getObjectId()))
+				registerPlayer(participant);
+			break;
+		case STATUS_COMBAT:
+			for (int i = 0; i < partOIDs.length; i++)
+			{
+				if (partOIDs[i] == participant.getObjectId())
+				{
+					part[i] = participant;
+					participant.setEventTeam(partTeams[i]);
+					if (partTKs[i])
+						participant.setEventPoints(0 - Config.AUTO_TVT_TK_PUNISH_POINTS_LOST);
+					participant.getAppearance().setNameColor(teamCR[partTeams[i]] +
+							teamCG[partTeams[i]] << 8 + teamCB[partTeams[i]] << 16);
+					updatePlayerTitle(participant, false);
+					checkEquipment(participant);
+					participant.teleToLocation(Config.AUTO_TVT_TEAM_LOCATIONS[partTeams[i]][0],
+							Config.AUTO_TVT_TEAM_LOCATIONS[partTeams[i]][1],
+							Config.AUTO_TVT_TEAM_LOCATIONS[partTeams[i]][2]);
+					break;
+				}
+			}
+			break;
+		}
+	}
+
+	private final void checkEquipment(L2PcInstance player)
+	{
+		L2ItemInstance item;
+		for (int i = 0; i < 25; i++)
+		{
+			synchronized (player.getInventory())
+			{
+				item = player.getInventory().getPaperdollItem(i);
+				if (item != null && !canUse(item.getItemId()))
+					player.useEquippableItem(item, true);
+			}
+		}
+	}
+
+	public static final boolean canUse(int itemId)
+	{
+		for (int id : Config.AUTO_TVT_DISALLOWED_ITEMS)
+			if (itemId == id)
+				return false;
+		return true;
+	}
+
+	private final int getWinnerTeam()
+	{
+		int maxPts = 0, winTeam = -1;
+		for (int i = 0; i < teamPts.length; i++)
+		{
+			if (teamPts[i] > maxPts)
+			{
+				maxPts = teamPts[i];
+				winTeam = i;
+			}
+		}
+		return winTeam;
+	}
+
+	private final void reward(L2PcInstance player)
+	{
+		for (int i = 0; i < Config.AUTO_TVT_REWARD_IDS.length; i++)
+		{
+			player.addItem("TvT Reward", Config.AUTO_TVT_REWARD_IDS[i],
+					Config.AUTO_TVT_REWARD_COUNT[i], null, false, true);
+			player.sendPacket(new SystemMessage(SystemMessageId.CONGRATULATIONS_RECEIVED_S1).addItemName(Config.AUTO_TVT_REWARD_IDS[i]));
+		}
+	}
+
+	public static final boolean isInProgress()
+	{
+		switch (getInstance().status)
+		{
+		case STATUS_PREPARATION:
+		case STATUS_COMBAT:
+			return true;
+		default:
+			return false;
+		}
+	}
+
+	public static final boolean isReged(L2PcInstance player)
+	{
+		return getInstance().isMember(player);
+	}
+
+	public static final boolean isPlaying(L2PcInstance player)
+	{
+		return isInProgress() && isReged(player);
+	}
+
+	public final boolean isMember(L2PcInstance player)
+	{
+		if (player == null)
+			return false;
+
+		switch (status)
+		{
+		case STATUS_NOT_IN_PROGRESS:
+			return false;
+		case STATUS_REGISTRATION:
+			return participants.contains(player);
+		case STATUS_PREPARATION:
+			return participants.contains(player) || isMember(player.getObjectId());
+		case STATUS_COMBAT:
+		case STATUS_REWARDS:
+			return isMember(player.getObjectId());
+		default:
+			return false;
+		}
+	}
+
+	private final boolean isMember(int oID)
+	{
+		for (int id : partOIDs)
+			if (id == oID)
+				return true;
+		return false;
+	}
+
+	private final boolean canJoin(L2PcInstance player)
+	{
+		// Level restrictions
+		boolean can = player.getLevel() <= Config.AUTO_TVT_LEVEL_MAX;
+		can &= player.getLevel() >= Config.AUTO_TVT_LEVEL_MIN;
+		// Cannot mess with Olympiad
+		can &= !(player.isInOlympiadMode() || Olympiad.getInstance().isRegistered(player));
+		// Cannot mess with raids or sieges
+		can &= !player.isInsideZone(L2Zone.FLAG_NOESCAPE);
+		can &= !(player.getMountType() == 2 && player.isInsideZone(L2Zone.FLAG_NOLANDING));
+		// Hero restriction
+		if (!Config.AUTO_TVT_REGISTER_HERO)
+			can &= !player.isHero();
+		// Cursed weapon owner restriction
+		if (!Config.AUTO_TVT_REGISTER_CURSED)
+			can &= !player.isCursedWeaponEquipped();
+		return can;
+	}
+
+	public final void registerPlayer(L2PcInstance player)
+	{
+		if (status != STATUS_REGISTRATION ||
+				participants.size() >= Config.AUTO_TVT_PARTICIPANTS_MAX)
+			player.sendPacket(SystemMessageId.REGISTRATION_PERIOD_OVER);
+		else if (!participants.contains(player))
+		{
+			if (!canJoin(player))
+			{
+				player.sendMessage("You do not meet the requirements to join " + evtName);
+				return;
+			}
+			participants.add(player);
+			registered.add(player.getObjectId());
+			player.sendMessage("You have been registered to " + evtName);
+		}
+		else
+			player.sendMessage("Already registered!");
+	}
+
+	public final void onKill(L2PcInstance killer, L2PcInstance victim)
+	{
+		if (status != STATUS_COMBAT || !isMember(killer) || !isMember(victim))
+			return;
+		victim.setKillsWithoutDeath(0);
+		if (killer.getEventTeam() != victim.getEventTeam())
+		{
+			if (Config.AUTO_TVT_GODLIKE_SYSTEM &&
+					killer.getKillsWithoutDeath() >= Config.AUTO_TVT_GODLIKE_MIN_KILLS)
+			{
+				killer.setEventPoints(killer.getEventPoints() + Config.AUTO_TVT_GODLIKE_POINT_MULTIPLIER);
+				updatePlayerTitle(killer, true);
+				if (Config.AUTO_TVT_GODLIKE_ANNOUNCE)
+				{
+					CreatureSay cs = new CreatureSay(0, SystemChatChannelId.Chat_Shout,
+							evtName, killer.getName() + ": God-like!");
+					for (L2PcInstance p : part)
+						p.sendPacket(cs);
+				}
+			}
+			else
+			{
+				killer.setEventPoints(killer.getEventPoints() + 1);
+				updatePlayerTitle(killer, false);
+			}
+			teamPts[killer.getEventTeam()]++;
+			killer.setKillsWithoutDeath(killer.getKillsWithoutDeath() + 1);
+			victim.setEventPoints(victim.getEventPoints() - 1);
+		}
+		else if (Config.AUTO_TVT_TK_PUNISH)
+		{
+			for (int i = 0; i < part.length; i++)
+				if (part[i] == killer)
+					partTKs[i] = true;
+			killer.setEventPoints(killer.getEventPoints() - Config.AUTO_TVT_TK_PUNISH_POINTS_LOST);
+			if (Config.AUTO_TVT_TK_PUNISH_CANCEL)
+				killer.stopAllEffects();
+			if (Config.AUTO_TVT_TK_RESET_GODLIKE)
+				killer.setKillsWithoutDeath(0);
+			if (Config.AUTO_TVT_TK_PUNISH_EFFECTS != null)
+			{
+				for (L2Skill s : Config.AUTO_TVT_TK_PUNISH_EFFECTS)
+				{
+					if (s == null) continue;
+					if (killer.getFirstEffect(s) != null)
+						killer.getFirstEffect(s).exit();
+					s.getEffects(killer, killer);
+				}
+			}
+			updatePlayerTitle(killer, false);
+		}
+		updatePlayerTitle(victim, false);
+	}
+
+	public final void revive(L2PcInstance participant)
+	{
+		participant.setIsPendingRevive(true);
+		participant.teleToLocation(Config.AUTO_TVT_TEAM_LOCATIONS[participant.getEventTeam()][0],
+				Config.AUTO_TVT_TEAM_LOCATIONS[participant.getEventTeam()][1],
+				Config.AUTO_TVT_TEAM_LOCATIONS[participant.getEventTeam()][2]);
+	}
+
+	public final void recover(L2PcInstance revived)
+	{
+		if (Config.AUTO_TVT_REVIVE_RECOVER && isPlaying(revived))
+		{
+			revived.getStatus().setCurrentCp(revived.getMaxCp());
+			revived.getStatus().setCurrentHpMp(revived.getMaxHp(), revived.getMaxMp());
+		}
+	}
+
+	private final void updatePlayerTitle(L2PcInstance player, boolean godlike)
+	{
+		if (godlike)
+			player.setTitle(Config.AUTO_TVT_GODLIKE_TITLE);
+		else
+			player.setTitle("Score: " + player.getEventPoints());
+		player.broadcastTitleInfo();
+	}
+
+	public final void onDisconnection(L2PcInstance player)
+	{
+		if (!isReged(player))
+			return;
+		switch (status)
+		{
+		case STATUS_REGISTRATION:
+			participants.remove(player);
+			break;
+		case STATUS_COMBAT:
+		case STATUS_REWARDS:
+			for (int i = 0; i < part.length; i++)
+				if (part[i] == player)
+				{
+					part[i] = null;
+					if (countTeamMembers(player.getEventTeam()) == 0)
+						eventEnd();
+				}
+			break;
+		}
+	}
+
+	private final int countTeamMembers(int team)
+	{
+		int result = 0;
+		for (L2PcInstance p : part)
+			if (p != null && p.getEventTeam() == team)
+				result++;
+		return result;
+	}
+
+	private final void removeDisconnected(int objID, Location loc, String title)
+	{
+		Connection con = null;
+		try
+		{
+			con = L2DatabaseFactory.getInstance().getConnection();
+			PreparedStatement ps = con.prepareStatement(REMOVE_DISCONNECTED_PLAYER);
+			ps.setInt(1, loc.getHeading());
+			if (Config.AUTO_TVT_OVERRIDE_TELE_BACK)
+			{
+				ps.setInt(2, Config.AUTO_TVT_DEFAULT_TELE_BACK[0]);
+				ps.setInt(3, Config.AUTO_TVT_DEFAULT_TELE_BACK[1]);
+				ps.setInt(4, Config.AUTO_TVT_DEFAULT_TELE_BACK[2]);
+			}
+			else
+			{
+				ps.setInt(2, loc.getX());
+				ps.setInt(3, loc.getY());
+				ps.setInt(4, loc.getZ());
+			}
+			ps.setString(5, title);
+			ps.setInt(6, objID);
+			ps.executeUpdate();
+			ps.close();
+		}
+		catch (SQLException e)
+		{
+			_log.error("Could not remove a disconnected TvT player!", e);
+		}
+		finally
+		{
+			L2DatabaseFactory.close(con);
+		}
+	}
+
+	private final int[] correctColor(int[] r, int[] g, int[] b, int rn, int gn, int bn,
+			int current) {
+		int[] result = { rn, gn, bn };
+		// Possible to do fast enough even if there are 32+ teams,
+		// But I don't think this "blind shot" idea is suited for that
+		if (Config.AUTO_TVT_TEAM_LOCATIONS.length > 32 || current == 0)
+			return result;
+
+		// TODO: calibrate the multiplier
+		int totalDiff, noticeable = (256 * 2) / Config.AUTO_TVT_TEAM_LOCATIONS.length;
+		while (true)
+		{
+			for (int i = 0; i < current; i++)
+			{
+				totalDiff = (Math.abs(result[0] - r[i]) + Math.abs(result[1] - g[i]) +
+						Math.abs(result[2] - b[i]));
+				if (totalDiff < noticeable)
+				{
+					result[0] = Rnd.get(256);
+					result[1] = Rnd.get(256);
+					result[2] = Rnd.get(256);
+				}
+				else
+					return result;
+			}
+		}
+	}
+}
Index: src/main/java/com/l2jfree/gameserver/network/clientpackets/EnterWorld.java
===================================================================
--- src/main/java/com/l2jfree/gameserver/network/clientpackets/EnterWorld.java	(revision 5950)
+++ src/main/java/com/l2jfree/gameserver/network/clientpackets/EnterWorld.java	(working copy)
@@ -47,6 +47,7 @@
import com.l2jfree.gameserver.model.entity.Hero;
import com.l2jfree.gameserver.model.entity.L2Event;
import com.l2jfree.gameserver.model.entity.Siege;
+import com.l2jfree.gameserver.model.entity.events.AutomatedTvT;
import com.l2jfree.gameserver.model.mapregion.TeleportWhereType;
import com.l2jfree.gameserver.model.olympiad.Olympiad;
import com.l2jfree.gameserver.model.quest.Quest;
@@ -222,6 +223,8 @@
			// no broadcast needed since the player will already spawn dead to others
			sendPacket(new Die(activeChar));

+		AutomatedTvT.getInstance().addDisconnected(activeChar);
+
		// engage and notify Partner
		if (Config.ALLOW_WEDDING)
		{
Index: src/main/java/com/l2jfree/gameserver/network/clientpackets/RequestGiveNickName.java
===================================================================
--- src/main/java/com/l2jfree/gameserver/network/clientpackets/RequestGiveNickName.java	(revision 5950)
+++ src/main/java/com/l2jfree/gameserver/network/clientpackets/RequestGiveNickName.java	(working copy)
@@ -18,6 +18,7 @@
import com.l2jfree.gameserver.model.L2Clan;
import com.l2jfree.gameserver.model.L2ClanMember;
import com.l2jfree.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jfree.gameserver.model.entity.events.AutomatedTvT;
import com.l2jfree.gameserver.network.SystemMessageId;
import com.l2jfree.gameserver.network.serverpackets.ActionFailed;
import com.l2jfree.gameserver.network.serverpackets.SystemMessage;
@@ -76,6 +77,11 @@
			requestFailed(SystemMessageId.PLEASE_INPUT_TITLE_LESS_128_CHARACTERS);
			return;
		}
+		else if (AutomatedTvT.isPlaying(activeChar))
+		{
+			requestFailed(SystemMessageId.NOT_WORKING_PLEASE_TRY_AGAIN_LATER);
+			return;
+		}

		L2ClanMember targetMember = activeChar.getClan().getClanMember(_target);
		if (targetMember == null)
Index: src/main/java/com/l2jfree/gameserver/network/clientpackets/RequestRestartPoint.java
===================================================================
--- src/main/java/com/l2jfree/gameserver/network/clientpackets/RequestRestartPoint.java	(revision 5950)
+++ src/main/java/com/l2jfree/gameserver/network/clientpackets/RequestRestartPoint.java	(working copy)
@@ -18,6 +18,7 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

+import com.l2jfree.Config;
import com.l2jfree.gameserver.ThreadPoolManager;
import com.l2jfree.gameserver.instancemanager.CastleManager;
import com.l2jfree.gameserver.instancemanager.ClanHallManager;
@@ -33,6 +34,7 @@
import com.l2jfree.gameserver.model.entity.Fort;
import com.l2jfree.gameserver.model.entity.FortSiege;
import com.l2jfree.gameserver.model.entity.Siege;
+import com.l2jfree.gameserver.model.entity.events.AutomatedTvT;
import com.l2jfree.gameserver.model.mapregion.TeleportWhereType;
import com.l2jfree.gameserver.model.zone.L2Zone;

@@ -229,6 +231,8 @@
			_log.warn("Living player [" + activeChar.getName() + "] called RestartPointPacket! Ban this player!");
			return;
		}
+		else if (AutomatedTvT.isPlaying(activeChar) && !Config.AUTO_TVT_REVIVE_SELF)
+			return;

		Castle castle = CastleManager.getInstance().getCastle(activeChar.getX(), activeChar.getY(), activeChar.getZ());
		if (castle != null && castle.getSiege().getIsInProgress())
Index: src/main/java/com/l2jfree/gameserver/network/clientpackets/UseItem.java
===================================================================
--- src/main/java/com/l2jfree/gameserver/network/clientpackets/UseItem.java	(revision 5950)
+++ src/main/java/com/l2jfree/gameserver/network/clientpackets/UseItem.java	(working copy)
@@ -23,6 +23,7 @@
import com.l2jfree.gameserver.instancemanager.FortSiegeManager;
import com.l2jfree.gameserver.model.L2ItemInstance;
import com.l2jfree.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jfree.gameserver.model.entity.events.AutomatedTvT;
import com.l2jfree.gameserver.model.itemcontainer.Inventory;
import com.l2jfree.gameserver.network.SystemMessageId;
import com.l2jfree.gameserver.network.serverpackets.ActionFailed;
@@ -170,6 +171,12 @@
		if (itemId == 57)
			return;

+		if (AutomatedTvT.isPlaying(activeChar) && !AutomatedTvT.canUse(itemId))
+		{
+			requestFailed(SystemMessageId.NOT_WORKING_PLEASE_TRY_AGAIN_LATER);
+			return;
+		}
+
		if (activeChar.isFishing() && !ShotTable.getInstance().isFishingShot(itemId))
		{
			// You cannot do anything else while fishing
Index: src/main/java/com/l2jfree/gameserver/network/serverpackets/Die.java
===================================================================
--- src/main/java/com/l2jfree/gameserver/network/serverpackets/Die.java	(revision 5950)
+++ src/main/java/com/l2jfree/gameserver/network/serverpackets/Die.java	(working copy)
@@ -24,6 +24,7 @@
import com.l2jfree.gameserver.model.actor.instance.L2PcInstance;
import com.l2jfree.gameserver.model.entity.FortSiege;
import com.l2jfree.gameserver.model.entity.Siege;
+import com.l2jfree.gameserver.model.entity.events.AutomatedTvT;

/**
  * sample
@@ -104,7 +105,17 @@

		writeC(0x0);

-		writeD(_charObjId); 
+		writeD(_charObjId);
+
+		if (_activeChar instanceof L2PcInstance && !((L2PcInstance) _activeChar).isGM() &&
+				AutomatedTvT.isPlaying((L2PcInstance) _activeChar) &&
+				!Config.AUTO_TVT_REVIVE_SELF)
+		{
+			for (int i = 0; i < 7; i++)
+				writeD(00);
+			return;
+		}
+
		writeD(_showVillage);
		writeD(_showClanhall);
		writeD(_showCastle);

 

Finally \o/

Guest
This topic is now closed to further replies.


  • Posts

    • Doesn't respond to DM on discord, I need the source to implement. He only gave me a compiled version with a bad script, I didn't want to complain here but it's a fact.
    • Hello friend, did you do it? Please send the link to the topic, please ❤️
    • ✨ We believe that technology is worthless without a human touch. A service can be fast, convenient, and modern, but if users are not treated with respect, not listened to, and their problems are not solved, all of this loses its meaning. We believe that respect should go both ways. And that’s why we want to build an audience that’s a pleasure to work with— people who respect us just as much as we respect them (at least a little).   Website: vibe-sms.com Telegram: https://t.me/vibe_sms  
    • 价格更新 – TikTok 账号与新产品. 在流量套利中,TikTok 账号起着关键作用。广告活动的成功以及套利者的收益直接取决于账号的质量。可靠且高质量的账号能够在推广中提供稳定性、信任和长期效果。 在我们这里,您只会找到经过验证的 TikTok 账号,适合开展广告投放、扩展受众和扩大收益。正确选择账号是高效套利的基础! 我们网上商店的完整产品目录: 账号: Telegram、Facebook、Reddit、Twitter (X)、Instagram、YouTube、TikTok、Discord、VK、LinkedIn、GitHub、Snapchat、Gmail、邮箱账号 (Outlook、Firstmail、Rambler、Onet、Gazeta、GMX、Yahoo、Proton、Web.de)、Google Voice、Google Ads 高级订阅: Telegram Premium、Twitter Premium X、YouTube Premium、Spotify Premium、Netflix Premium、Discord Nitro、ChatGPT Plus/PRO、XBOX Game Pass 附加服务: Telegram Stars、代理 (IPv4、IPv6、ISP、移动)、VPN (Outline、WireGuard 等)、VDS/RDP 服务器 优惠码: AUGUST2025 (九折优惠) 支付方式: 银行卡 · 加密货币 · 其他常用方式 相关链接: ➡ 网店: 点击 ➡ Telegram 机器人: 点击 ➡ SMM 面板: 点击 – 推广您的社交媒体账号 使用我们的 SMM 面板 可提升 Facebook、Instagram、Telegram、Spotify、Soundcloud、YouTube、Reddit、Threads、Kick、Discord、LinkedIn、Likee、VK、Twitch、Kwai、Reddit、网站流量、TikTok、Trust Pilot、Apple Music、Tripadvisor、Snapchat 及其他数字产品。 首次体验 SMM 面板可获得 1 美元:只需在 我们的网站 (支持) 提交工单,主题填写 “Get Trial Bonus”。 更新后的TikTok 账号种类与价格调整: TIKTOK 新账号 TikTok 蓝 V 认证账号 | 真实账号,拥有真实粉丝与互动 | 官方认证 | 当前价格: $2500 TikTok 高质量新自动注册账号 | 国家:美国和欧洲 | 完整访问权限 (包含邮箱) | 起价 $0.2 TIKTOK – 空号自动注册 II 通过 @RAMBLER.RU/@FIRSTMAIL 验证 II 包含邮箱,使用 RU IP 注册 | 起价 $0.1 自动注册 TikTok 账号 II 通过 rambler.ru 邮箱验证,包含邮箱 II 性别混合 II 拉丁名 II 空白资料 II 使用混合 IP 注册 | 起价 $0.1 粉丝账号 自动注册 TikTok 账号 II 100+ 粉丝 II 通过邮箱验证 @hotmail/@outlook/@firstmail/@rambler,包含有效邮箱 II 性别混合 II 拉丁名 II 使用混合 IP 注册 | 起价 $0.39 自动注册 TikTok 账号 II 1000+ 粉丝 II 邮箱验证,包含有效邮箱 II 性别混合 II 拉丁名 II 支持开播+可加链接 II 使用混合 IP 注册 | 起价 $2.5 自动注册 TikTok 账号 II 5000 粉丝 II 邮箱验证,包含有效邮箱 II 性别混合 II 拉丁名 II 支持开播+可加链接 II 使用混合 IP 注册 | 起价 $10 自动注册 TikTok 账号 II 10,000+ 粉丝 II 邮箱验证,包含有效邮箱 II 性别混合 II 拉丁名 II 支持开播+可加链接 II 使用混合 IP 注册 | 起价 $19 老号 (有/无粉丝) TikTok 高质量老号 | 年份:2022-2024 | 国家:混合 | 完整访问权限 (包含邮箱) | 起价 $0.35 TikTok 高质量老号 (粉丝数量 100-10,000 可选) | 年份:2022-2024 | 国家:混合 | 完整访问权限 (包含邮箱) | 起价 $0.89 TIKTOK 广告账号 TIKTOK 广告账号 | 区域:欧洲 | 预付 | 手工注册 | 邮箱访问 + Cookies + VAT 信息 | 起价 $1 TIKTOK 广告账号 | 区域:美国 | 预付 | 手工注册 | 邮箱访问 + Cookies + VAT 信息 | 起价 $1 TIKTOK 广告账号 | 区域:美国 | 企业认证 + 后付 | 手工注册 | 邮箱访问 + Cookies + VAT 信息 | 起价 $3.5 TIKTOK 广告账号 | 区域:欧洲 | 企业认证 + 后付 | 手工注册 | 邮箱访问 + Cookies + VAT 信息 | 起价 $3.5 TIKTOK 广告账号 | 区域:欧洲 | 后付+企业中心 | 3 个广告账户 + 1 个个人账户 | 可能包含 $20-$100 广告优惠券 | 手工注册 | 邮箱访问 + Cookies + VAT 信息 | 起价 $8 TIKTOK 广告账号 | 区域:美国 | 后付+企业中心 | 3 个广告账户 + 1 个个人账户 | 可能包含 $20-$100 广告优惠券 | 手工注册 | 邮箱访问 + Cookies + VAT 信息 | 起价 $8 老客户 – 额外 折扣 和 优惠码! 9–8 折 或 注册赠送 $1 如果您想获得注册赠送 $1 或首次购买享受 9–8 折优惠,可以留言: "SEND ME BONUS, MY USERNAME IS..." 您也可以在首次购买时使用优惠码: SOCNET (85 折优惠) 联系方式与支持: ➡ Telegram: https://t.me/socnet_support ➡ Telegram 频道: https://t.me/accsforyou_shop ➡ WhatsApp: https://wa.me/79051904467 ➡ WhatsApp 频道: https://whatsapp.com/channel/0029Vau0CMX002TGkD4uHa2n ➡ Discord: socnet_support ➡ Discord 服务器: https://discord.gg/y9AStFFsrh ➡ ✉ 邮箱: solomonbog@socnet.store 通过以上联系方式您还可以: — 咨询批发采购 — 建立合作关系 (当前合作伙伴: https://socnet.bgng.io/partners) — 成为我们的供应商 SocNet – 数字商品与高级订阅商店
    • 价格更新 – TikTok 账号与新产品. 在流量套利中,TikTok 账号起着关键作用。广告活动的成功以及套利者的收益直接取决于账号的质量。可靠且高质量的账号能够在推广中提供稳定性、信任和长期效果。 在我们这里,您只会找到经过验证的 TikTok 账号,适合开展广告投放、扩展受众和扩大收益。正确选择账号是高效套利的基础! 我们网上商店的完整产品目录: 账号: Telegram、Facebook、Reddit、Twitter (X)、Instagram、YouTube、TikTok、Discord、VK、LinkedIn、GitHub、Snapchat、Gmail、邮箱账号 (Outlook、Firstmail、Rambler、Onet、Gazeta、GMX、Yahoo、Proton、Web.de)、Google Voice、Google Ads 高级订阅: Telegram Premium、Twitter Premium X、YouTube Premium、Spotify Premium、Netflix Premium、Discord Nitro、ChatGPT Plus/PRO、XBOX Game Pass 附加服务: Telegram Stars、代理 (IPv4、IPv6、ISP、移动)、VPN (Outline、WireGuard 等)、VDS/RDP 服务器 优惠码: AUGUST2025 (九折优惠) 支付方式: 银行卡 · 加密货币 · 其他常用方式 相关链接: ➡ 网店: 点击 ➡ Telegram 机器人: 点击 ➡ SMM 面板: 点击 – 推广您的社交媒体账号 使用我们的 SMM 面板 可提升 Facebook、Instagram、Telegram、Spotify、Soundcloud、YouTube、Reddit、Threads、Kick、Discord、LinkedIn、Likee、VK、Twitch、Kwai、Reddit、网站流量、TikTok、Trust Pilot、Apple Music、Tripadvisor、Snapchat 及其他数字产品。 首次体验 SMM 面板可获得 1 美元:只需在 我们的网站 (支持) 提交工单,主题填写 “Get Trial Bonus”。 更新后的TikTok 账号种类与价格调整: TIKTOK 新账号 TikTok 蓝 V 认证账号 | 真实账号,拥有真实粉丝与互动 | 官方认证 | 当前价格: $2500 TikTok 高质量新自动注册账号 | 国家:美国和欧洲 | 完整访问权限 (包含邮箱) | 起价 $0.2 TIKTOK – 空号自动注册 II 通过 @RAMBLER.RU/@FIRSTMAIL 验证 II 包含邮箱,使用 RU IP 注册 | 起价 $0.1 自动注册 TikTok 账号 II 通过 rambler.ru 邮箱验证,包含邮箱 II 性别混合 II 拉丁名 II 空白资料 II 使用混合 IP 注册 | 起价 $0.1 粉丝账号 自动注册 TikTok 账号 II 100+ 粉丝 II 通过邮箱验证 @hotmail/@outlook/@firstmail/@rambler,包含有效邮箱 II 性别混合 II 拉丁名 II 使用混合 IP 注册 | 起价 $0.39 自动注册 TikTok 账号 II 1000+ 粉丝 II 邮箱验证,包含有效邮箱 II 性别混合 II 拉丁名 II 支持开播+可加链接 II 使用混合 IP 注册 | 起价 $2.5 自动注册 TikTok 账号 II 5000 粉丝 II 邮箱验证,包含有效邮箱 II 性别混合 II 拉丁名 II 支持开播+可加链接 II 使用混合 IP 注册 | 起价 $10 自动注册 TikTok 账号 II 10,000+ 粉丝 II 邮箱验证,包含有效邮箱 II 性别混合 II 拉丁名 II 支持开播+可加链接 II 使用混合 IP 注册 | 起价 $19 老号 (有/无粉丝) TikTok 高质量老号 | 年份:2022-2024 | 国家:混合 | 完整访问权限 (包含邮箱) | 起价 $0.35 TikTok 高质量老号 (粉丝数量 100-10,000 可选) | 年份:2022-2024 | 国家:混合 | 完整访问权限 (包含邮箱) | 起价 $0.89 TIKTOK 广告账号 TIKTOK 广告账号 | 区域:欧洲 | 预付 | 手工注册 | 邮箱访问 + Cookies + VAT 信息 | 起价 $1 TIKTOK 广告账号 | 区域:美国 | 预付 | 手工注册 | 邮箱访问 + Cookies + VAT 信息 | 起价 $1 TIKTOK 广告账号 | 区域:美国 | 企业认证 + 后付 | 手工注册 | 邮箱访问 + Cookies + VAT 信息 | 起价 $3.5 TIKTOK 广告账号 | 区域:欧洲 | 企业认证 + 后付 | 手工注册 | 邮箱访问 + Cookies + VAT 信息 | 起价 $3.5 TIKTOK 广告账号 | 区域:欧洲 | 后付+企业中心 | 3 个广告账户 + 1 个个人账户 | 可能包含 $20-$100 广告优惠券 | 手工注册 | 邮箱访问 + Cookies + VAT 信息 | 起价 $8 TIKTOK 广告账号 | 区域:美国 | 后付+企业中心 | 3 个广告账户 + 1 个个人账户 | 可能包含 $20-$100 广告优惠券 | 手工注册 | 邮箱访问 + Cookies + VAT 信息 | 起价 $8 老客户 – 额外 折扣 和 优惠码! 9–8 折 或 注册赠送 $1 如果您想获得注册赠送 $1 或首次购买享受 9–8 折优惠,可以留言: "SEND ME BONUS, MY USERNAME IS..." 您也可以在首次购买时使用优惠码: SOCNET (85 折优惠) 联系方式与支持: ➡ Telegram: https://t.me/socnet_support ➡ Telegram 频道: https://t.me/accsforyou_shop ➡ WhatsApp: https://wa.me/79051904467 ➡ WhatsApp 频道: https://whatsapp.com/channel/0029Vau0CMX002TGkD4uHa2n ➡ Discord: socnet_support ➡ Discord 服务器: https://discord.gg/y9AStFFsrh ➡ ✉ 邮箱: solomonbog@socnet.store 通过以上联系方式您还可以: — 咨询批发采购 — 建立合作关系 (当前合作伙伴: https://socnet.bgng.io/partners) — 成为我们的供应商 SocNet – 数字商品与高级订阅商店
  • Topics

×
×
  • Create New...

AdBlock Extension Detected!

Our website is made possible by displaying online advertisements to our members.

Please disable AdBlock browser extension first, to be able to use our community.

I've Disabled AdBlock