Noticias:

No tienes permiso para ver los enlaces. Para poder verlos Registrate o Conectate.

Menú Principal

Scheme Buffer para Hall - Ayuda

Iniciado por tevsko, Oct 16, 2025, 02:42 PM

Tema anterior - Siguiente tema

tevsko

Que tal , estoy implementando que el Hall de clanes tenga buffer como el Scheme,  el inconveniente es que no me guarda los cambios en la DB, mientras este en linea funciona pero al salir del juego, la tabla no guarda los skilles,
e intentado ponerlo denttro del NPc del hall
editando
<button value="Support Magic" action="bypass -h npc_%objectId%_functions support"

por <button value="Support Magic" action="bypass -h npc_%objectId%_functions SchemeBuffer"
pero de esa forma no logro a que responda,
alguien que me de una mano, para que funcione desde el mismo Npc del hall ?

Aclaro, cuando funcione pondré bien la lista de skilles,
+++ b/L2J_Mobius_C6_Interlude/dist/db_installer/sql/game/buffer_schemesCustom.sql
@@ -0,0 +1,5 @@
+CREATE TABLE IF NOT EXISTS `buffer_schemescustom` (
+  `object_id` INT UNSIGNED NOT NULL DEFAULT '0',
+  `scheme_name` VARCHAR(16) NOT NULL DEFAULT 'default',
+  `skills` VARCHAR(200) NOT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
\ No newline at end of file

d
+++ b/L2J_Mobius_C6_Interlude/dist/game/config/custom/SchemeBufferCustom.ini
@@ -0,0 +1,10 @@
+# ---------------------------------------------------------------------------
+# Scheme Buffer
+# ---------------------------------------------------------------------------
+# Also check data\SchemeBufferSkills.xml
+
+# Maximum number of available schemes per player.
+BufferMaxSchemesPerChar = 4
+
+# Static cost of buffs ; override skills price if different of -1.
+BufferStaticCostPerBuff = -1

+++ b/L2J_Mobius_C6_Interlude/dist/game/data/SchemeBufferSkillsCustom.xml
@@ -0,0 +1,69 @@
+<?xml version='1.0' encoding='utf-8'?>
+<list xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="xsd/SchemeBufferSkills.xsd">
+	<category type="Buffs">
+		<buff id="1035" level="1" price="0" desc="Increases resistance to mental attacks." /> <!-- Mental Shield -->
+		<buff id="1036" level="1" price="0" desc="Increases M. Def." /> <!-- Magic Barrier -->
+		<buff id="1040" level="1" price="0" desc="Increases P. Def." /> <!-- Shield -->
+		<buff id="1045" level="1" price="0" desc="Increases maximum HP." /> <!-- Blessed Body -->
+		<buff id="1048" level="1" price="0" desc="Increases maximum MP." /> <!-- Blessed Soul -->
+		<buff id="1059" level="1" price="0" desc="Increases M. Atk." /> <!-- Empower -->
+		<buff id="1062" level="1" price="0" desc="Reduces def. and increase atk. power." /> <!-- Berserker Spirit -->
+		<buff id="1068" level="1" price="0" desc="Increases P. Atk." /> <!-- Might -->
+		<buff id="1077" level="1" price="0" desc="Increases critical attack rate." /> <!-- Focus -->
+		<buff id="1078" level="1" price="0" desc="Increases magic concentration." /> <!-- Concentration -->
+		<buff id="1085" level="1" price="0" desc="Increases Casting Spd." /> <!-- Acumen -->
+		<buff id="1086" level="1" price="0" desc="Increases Atk. Spd." /> <!-- Haste -->
+		<buff id="1087" level="1" price="0" desc="Increases Evasion." /> <!-- Agility -->
+		<buff id="1204" level="1" price="0" desc="Increases Speed." /> <!-- Wind Walk -->
+		<buff id="1240" level="1" price="0" desc="Increases Accuracy." /> <!-- Guidance -->
+		<buff id="1242" level="1" price="0" desc="Increases critical attack." /> <!-- Death Whisper -->
+		<buff id="1243" level="1" price="0" desc="Increases shield defense rate." /> <!-- Bless Shield -->
+		<buff id="1259" level="1" price="0" desc="Increases resistance to stun attack." /> <!-- Resist Shock -->
+		<buff id="1268" level="1" price="0" desc="Restores HP using inflicted damage." /> <!-- Vampiric Rage -->
+		<buff id="1303" level="1" price="0" desc="Increases crit. rate of magic attacks." /> <!-- Wild Magic -->
+		<buff id="1304" level="1" price="0" desc="Increases shield defense power." /> <!-- Advanced Block -->
+		<buff id="1352" level="1" price="0" desc="Increases resistance to atures." /> <!-- Elemental Protection -->
+		<buff id="1353" level="1" price="0" desc="Increases resistance to dark attack." /> <!-- Divine Protection -->
+		<buff id="1354" level="1" price="0" desc="Increases resistance to de-buff attack." /> <!-- Arcane Protection -->
+		<buff id="1355" level="1" price="0" desc="Increases mage abilities." /> <!-- Prophecy of Water -->
+		<buff id="1356" level="1" price="0" desc="Increases fighter abilities." /> <!-- Prophecy of Fire -->
+		<buff id="1357" level="1" price="0" desc="Increases dagger abilities." /> <!-- Prophecy of Wind -->
+		<buff id="1363" level="1" price="0" desc="Increases combat abilities." /> <!-- Chant of Victory -->
+		<buff id="1388" level="1" price="0" desc="Increases P. Atk." /> <!-- Greater Might -->
+		<buff id="1389" level="1" price="0" desc="Increases P. Def." /> <!-- Greater Shield -->
+		<buff id="1390" level="1" price="0" desc="Increases P. Atk." /> <!-- War Chant -->
+		<buff id="1391" level="1" price="0" desc="Increases P. Def." /> <!-- Earth Chant -->
+		<buff id="1397" level="1" price="0" desc="Decreases MP consumption rate." /> <!-- Clarity -->
+		<buff id="1413" level="1" price="0" desc="Increases mage abilities." /> <!-- Magnus' Chant -->
+	</category>
+	<category type="Dances">
+		<buff id="271" level="1" price="0" desc="Increases P. Atk." /> <!-- Dance of the Warrior -->
+		<buff id="272" level="1" price="0" desc="Increases Accuracy." /> <!-- Dance of Inspiration -->
+		<buff id="273" level="1" price="0" desc="Increases M. Atk." /> <!-- Dance of the Mystic -->
+		<buff id="274" level="1" price="0" desc="Increases critical damage." /> <!-- Dance of Fire -->
+		<buff id="275" level="1" price="0" desc="Increases attack speed." /> <!-- Dance of Fury -->
+		<buff id="276" level="1" price="0" desc="Increases Casting Spd." /> <!-- Dance of Concentration -->
+		<buff id="277" level="1" price="0" desc="Sacred power to physical attack." /> <!-- Dance of Light -->
+		<buff id="307" level="1" price="0" desc="Increases water resistance." /> <!-- Dance of Aqua Guard -->
+		<buff id="309" level="1" price="0" desc="Increases earth resistance." /> <!-- Dance of Earth Guard -->
+		<buff id="310" level="1" price="0" desc="Restores HP by inflicted damage." /> <!-- Dance of the Vampire -->
+		<buff id="311" level="1" price="0" desc="Increases resistance to terrain damage." /> <!-- Dance of Protection -->
+		<buff id="365" level="1" price="0" desc="Increases rate of magic crit. damage." /> <!-- Siren's Dance -->
+	</category>
+	<category type="Songs">
+		<buff id="264" level="1" price="0" desc="Increases P. Def." /> <!-- Song of Earth -->
+		<buff id="265" level="1" price="0" desc="Increases HP regeneration." /> <!-- Song of Life -->
+		<buff id="266" level="1" price="0" desc="Increases Evasion." /> <!-- Song of Water -->
+		<buff id="267" level="1" price="0" desc="Increases M. Def." /> <!-- Song of Warding -->
+		<buff id="268" level="1" price="0" desc="Increases movement." /> <!-- Song of Wind -->
+		<buff id="269" level="1" price="0" desc="Increases critical rate." /> <!-- Song of Hunter -->
+		<buff id="270" level="1" price="0" desc="Increases resistance to dark magic." /> <!-- Song of Invocation -->
+		<buff id="304" level="1" price="0" desc="Increases maximum HP." /> <!-- Song of Vitality -->
+		<buff id="305" level="1" price="0" desc="Reflects damage received." /> <!-- Song of Vengeance -->
+		<buff id="306" level="1" price="0" desc="Increases resistance to fire." /> <!-- Song of Flame Guard -->
+		<buff id="308" level="1" price="0" desc="Increases resistance to wind." /> <!-- Song of Storm Guard -->
+		<buff id="349" level="1" price="0" desc="Decreases re-use time." /> <!-- Song of Renewal -->
+		<buff id="363" level="1" price="0" desc="Increases MP regeneration rate." /> <!-- Song of Meditation -->
+		<buff id="364" level="1" price="0" desc="Decreases re-use time of physical skills." /> <!-- Song of Champion -->
+	</category>
+</list>
\ No newline at end of file

diff --git a/L2J_Mobius_C6_Interlude/java/org/l2jmobius/Config.java b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/Config.java
index 2ddf7564d6..cd74752e31 100644
--- a/L2J_Mobius_C6_Interlude/java/org/l2jmobius/Config.java
+++ b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/Config.java
@@ -93,6 +93,7 @@ public class Config
 	private static final String OFFLINE_CONFIG_FILE = "./config/custom/Offline.ini";
 	private static final String OTHER_CONFIG_FILE = "./config/custom/Other.ini";
 	private static final String SCHEME_BUFFER_CONFIG_FILE = "./config/custom/SchemeBuffer.ini";
+	private static final String SCHEME_BUFFER_CUSTOM_CONFIG_FILE = "./config/custom/SchemeBufferCustom.ini";	
 	private static final String EVENT_REBIRTH_CONFIG_FILE = "./config/custom/Rebirth.ini";
 	private static final String EVENT_WEDDING_CONFIG_FILE = "./config/custom/Wedding.ini";
 	// login
@@ -563,7 +564,9 @@ public class Config
 	
 	public static int BUFFER_MAX_SCHEMES;
 	public static int BUFFER_STATIC_BUFF_COST;
-	
+	public static int BUFFER_MAX_SCHEMES_CUSTOM;
+	public static int BUFFER_STATIC_BUFF_COST_CUSTOM;	
+
 	public static boolean OFFLINE_TRADE_ENABLE;

@@ -1784,6 +1794,11 @@ public class Config
 		BUFFER_MAX_SCHEMES = shemeBufferConfig.getInt("BufferMaxSchemesPerChar", 4);
 		BUFFER_STATIC_BUFF_COST = shemeBufferConfig.getInt("BufferStaticCostPerBuff", -1);
 	}
+	{
+		final PropertiesParser shemeBufferConfig = new PropertiesParser(SCHEME_BUFFER_CUSTOM_CONFIG_FILE);
+		BUFFER_MAX_SCHEMES_CUSTOM = shemeBufferConfig.getInt("BufferMaxSchemesPerChar", 4);
+		BUFFER_STATIC_BUFF_COST_CUSTOM = shemeBufferConfig.getInt("BufferStaticCostPerBuff", -1);
+	}
 	
 	public static void loadOfflineConfig()
 	{

+++ b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/datatables/SchemeBufferTableCustom.java
@@ -0,0 +1,282 @@
+/*
+ * This file is part of the L2J Mobius project.
+ * 
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.l2jmobius.gameserver.datatables;
+
+import java.io.File;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Logger;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+
+import org.l2jmobius.Config;
+import org.l2jmobius.commons.database.DatabaseFactory;
+import org.l2jmobius.gameserver.model.holders.BuffSkillHolder;
+
+/**
+ * This class loads available skills and stores players' buff schemes into _schemesTable.
+ */
+public class SchemeBufferTableCustom
+{
+	private static final Logger LOGGER = Logger.getLogger(SchemeBufferTableCustom.class.getName());
+	
+	private static final String LOAD_SCHEMES = "SELECT * FROM buffer_schemescustom";
+	private static final String DELETE_SCHEMES = "TRUNCATE TABLE buffer_schemescustom";
+	private static final String INSERT_SCHEME = "INSERT INTO buffer_schemescustom (object_id, scheme_name, skills) VALUES (?,?,?)";
+	
+	private final Map<Integer, Map<String, List<Integer>>> _schemesTable = new ConcurrentHashMap<>();
+	private final Map<Integer, BuffSkillHolder> _availableBuffs = new LinkedHashMap<>();
+	
+	public SchemeBufferTableCustom()
+	{
+		int count = 0;
+		
+		try (Connection con = DatabaseFactory.getConnection())
+		{
+			final PreparedStatement st = con.prepareStatement(LOAD_SCHEMES);
+			final ResultSet rs = st.executeQuery();
+			
+			while (rs.next())
+			{
+				final int objectId = rs.getInt("object_id");
+				final String schemeName = rs.getString("scheme_name");
+				final String[] skills = rs.getString("skills").split(",");
+				final ArrayList<Integer> schemeList = new ArrayList<>();
+				for (String skill : skills)
+				{
+					// Don't feed the skills list if the list is empty.
+					if (skill.isEmpty())
+					{
+						break;
+					}
+					
+					schemeList.add(Integer.parseInt(skill));
+				}
+				
+				setScheme(objectId, schemeName, schemeList);
+				count++;
+			}
+			
+			rs.close();
+			st.close();
+		}
+		catch (Exception e)
+		{
+			LOGGER.warning("SchemeBufferTableCustom: Failed to load buff schemes : " + e);
+		}
+		
+		try
+		{
+			final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+			final DocumentBuilder db = dbf.newDocumentBuilder();
+			final Document doc = db.parse(new File("./data/SchemeBufferSkillsCustom.xml"));
+			final Node n = doc.getFirstChild();
+			for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
+			{
+				if (!d.getNodeName().equalsIgnoreCase("category"))
+				{
+					continue;
+				}
+				
+				final String category = d.getAttributes().getNamedItem("type").getNodeValue();
+				for (Node c = d.getFirstChild(); c != null; c = c.getNextSibling())
+				{
+					if (!c.getNodeName().equalsIgnoreCase("buff"))
+					{
+						continue;
+					}
+					
+					final NamedNodeMap attrs = c.getAttributes();
+					final int skillId = Integer.parseInt(attrs.getNamedItem("id").getNodeValue());
+					_availableBuffs.put(skillId, new BuffSkillHolder(skillId, Integer.parseInt(attrs.getNamedItem("level").getNodeValue()), Integer.parseInt(attrs.getNamedItem("price").getNodeValue()), category, attrs.getNamedItem("desc").getNodeValue()));
+				}
+			}
+		}
+		catch (Exception e)
+		{
+			LOGGER.warning("SchemeBufferTableCustom: Failed to load buff info : " + e);
+		}
+		LOGGER.info("SchemeBufferTableCustom: Loaded " + count + " players schemes and " + _availableBuffs.size() + " available buffs.");
+	}
+	
+	public void saveSchemes()
+	{
+		try (Connection con = DatabaseFactory.getConnection())
+		{
+			// Delete all entries from database.
+			try (PreparedStatement st = con.prepareStatement(DELETE_SCHEMES))
+			{
+				st.execute();
+			}
+			
+			// Save _schemesTable content.
+			try (PreparedStatement st = con.prepareStatement(INSERT_SCHEME))
+			{
+				for (Map.Entry<Integer, Map<String, List<Integer>>> player : _schemesTable.entrySet())
+				{
+					for (Map.Entry<String, List<Integer>> scheme : player.getValue().entrySet())
+					{
+						// Build a String composed of skill ids seperated by a ",".
+						final StringBuilder sb = new StringBuilder();
+						for (int skillId : scheme.getValue())
+						{
+							sb.append(skillId + ",");
+						}
+						
+						// Delete the last "," : must be called only if there is something to delete !
+						if (sb.length() > 0)
+						{
+							sb.setLength(sb.length() - 1);
+						}
+						
+						st.setInt(1, player.getKey());
+						st.setString(2, scheme.getKey());
+						st.setString(3, sb.toString());
+						st.addBatch();
+					}
+				}
+				st.executeBatch();
+			}
+		}
+		catch (Exception e)
+		{
+			LOGGER.warning("BufferTableScheme: Error while saving schemes : " + e);
+		}
+	}
+	
+	public void setScheme(int playerId, String schemeName, List<Integer> list)
+	{
+		if (!_schemesTable.containsKey(playerId))
+		{
+			_schemesTable.put(playerId, new TreeMap<>(String.CASE_INSENSITIVE_ORDER));
+		}
+		else if (_schemesTable.get(playerId).size() >= Config.BUFFER_MAX_SCHEMES_CUSTOM)
+		{
+			return;
+		}
+		
+		_schemesTable.get(playerId).put(schemeName, list);
+	}
+	
+	/**
+	 * @param playerId : The player objectId to check.
+	 * @return the list of schemes for a given player.
+	 */
+	public Map<String, List<Integer>> getPlayerSchemes(int playerId)
+	{
+		return _schemesTable.get(playerId);
+	}
+	
+	/**
+	 * @param playerId : The player objectId to check.
+	 * @param schemeName : The scheme name to check.
+	 * @return the List holding skills for the given scheme name and player, or null (if scheme or player isn't registered).
+	 */
+	public List<Integer> getScheme(int playerId, String schemeName)
+	{
+		if ((_schemesTable.get(playerId) == null) || (_schemesTable.get(playerId).get(schemeName) == null))
+		{
+			return Collections.emptyList();
+		}
+		return _schemesTable.get(playerId).get(schemeName);
+	}
+	
+	/**
+	 * @param playerId : The player objectId to check.
+	 * @param schemeName : The scheme name to check.
+	 * @param skillId : The skill id to check.
+	 * @return true if the skill is already registered on the scheme, or false otherwise.
+	 */
+	public boolean getSchemeContainsSkill(int playerId, String schemeName, int skillId)
+	{
+		final List<Integer> skills = getScheme(playerId, schemeName);
+		if (skills.isEmpty())
+		{
+			return false;
+		}
+		
+		for (int id : skills)
+		{
+			if (id == skillId)
+			{
+				return true;
+			}
+		}
+		return false;
+	}
+	
+	/**
+	 * @param groupType : The type of skills to return.
+	 * @return a list of skills ids based on the given groupType.
+	 */
+	public List<Integer> getSkillsIdsByType(String groupType)
+	{
+		final List<Integer> skills = new ArrayList<>();
+		for (BuffSkillHolder skill : _availableBuffs.values())
+		{
+			if (skill.getType().equalsIgnoreCase(groupType))
+			{
+				skills.add(skill.getId());
+			}
+		}
+		return skills;
+	}
+	
+	/**
+	 * @return a list of all buff types available.
+	 */
+	public List<String> getSkillTypes()
+	{
+		final List<String> skillTypes = new ArrayList<>();
+		for (BuffSkillHolder skill : _availableBuffs.values())
+		{
+			if (!skillTypes.contains(skill.getType()))
+			{
+				skillTypes.add(skill.getType());
+			}
+		}
+		return skillTypes;
+	}
+	
+	public BuffSkillHolder getAvailableBuff(int skillId)
+	{
+		return _availableBuffs.get(skillId);
+	}
+	
+	public static SchemeBufferTableCustom getInstance()
+	{
+		return SingletonHolder.INSTANCE;
+	}
+	
+	private static class SingletonHolder
+	{
+		protected static final SchemeBufferTableCustom INSTANCE = new SchemeBufferTableCustom();
+	}
+}
\ No newline at end of file

+++ b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/model/actor/instance/SchemeBufferCustomInstance.java
@@ -0,0 +1,441 @@
+/*
+ * This file is part of the L2J Mobius project.
+ * 
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.l2jmobius.gameserver.model.actor.instance;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import org.l2jmobius.Config;
+import org.l2jmobius.commons.util.StringUtil;
+import org.l2jmobius.gameserver.datatables.SchemeBufferTableCustom;
+import org.l2jmobius.gameserver.datatables.SkillTable;
+import org.l2jmobius.gameserver.model.actor.Creature;
+import org.l2jmobius.gameserver.model.actor.Summon;
+import org.l2jmobius.gameserver.model.actor.templates.NpcTemplate;
+import org.l2jmobius.gameserver.network.serverpackets.NpcHtmlMessage;
+import org.l2jmobius.gameserver.util.Util;
+
+public class SchemeBufferCustomInstance extends FolkInstance
+{
+	private static final int PAGE_LIMIT = 6;
+	
+	public SchemeBufferCustomInstance(int objectId, NpcTemplate template)
+	{
+		super(objectId, template);
+	}
+	
+	@Override
+	public void onBypassFeedback(PlayerInstance player, String command)
+	{
+		// Simple hack to use createscheme bypass with a space.
+		command = command.replace("createscheme ", "createscheme;");
+		
+		final StringTokenizer st = new StringTokenizer(command, ";");
+		final String currentCommand = st.nextToken();
+		if (currentCommand.startsWith("menu"))
+		{
+			final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
+			html.setFile(getHtmlPath(getNpcId(), 0));
+			html.replace("%objectId%", getObjectId());
+			player.sendPacket(html);
+		}
+		else if (currentCommand.startsWith("cleanup"))
+		{
+			player.stopAllEffects();
+			
+			final Summon summon = player.getPet();
+			if (summon != null)
+			{
+				summon.stopAllEffects();
+			}
+			
+			final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
+			html.setFile(getHtmlPath(getNpcId(), 0));
+			html.replace("%objectId%", getObjectId());
+			player.sendPacket(html);
+		}
+		else if (currentCommand.startsWith("heal"))
+		{
+			player.setCurrentHpMp(player.getMaxHp(), player.getMaxMp());
+			player.setCurrentCp(player.getMaxCp());
+			
+			final Summon summon = player.getPet();
+			if (summon != null)
+			{
+				summon.setCurrentHpMp(summon.getMaxHp(), summon.getMaxMp());
+			}
+			
+			final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
+			html.setFile(getHtmlPath(getNpcId(), 0));
+			html.replace("%objectId%", getObjectId());
+			player.sendPacket(html);
+		}
+		else if (currentCommand.startsWith("support"))
+		{
+			showGiveBuffsWindow(player);
+		}
+		else if (currentCommand.startsWith("givebuffs"))
+		{
+			final String schemeName = st.nextToken();
+			final int cost = Integer.parseInt(st.nextToken());
+			Creature target = null;
+			if (st.hasMoreTokens())
+			{
+				final String targetType = st.nextToken();
+				if ((targetType != null) && targetType.equalsIgnoreCase("pet"))
+				{
+					target = player.getPet();
+				}
+			}
+			else
+			{
+				target = player;
+			}
+			
+			if (target == null)
+			{
+				player.sendMessage("You don't have a pet.");
+			}
+			else if ((cost == 0) || player.reduceAdena("NPC Buffer", cost, this, true))
+			{
+				for (int skillId : SchemeBufferTableCustom.getInstance().getScheme(player.getObjectId(), schemeName))
+				{
+					SkillTable.getInstance().getSkill(skillId, SchemeBufferTableCustom.getInstance().getAvailableBuff(skillId).getLevel()).getEffects(this, target);
+				}
+			}
+		}
+		else if (currentCommand.startsWith("editschemes"))
+		{
+			showEditSchemeWindow(player, st.nextToken(), st.nextToken(), Integer.parseInt(st.nextToken()));
+		}
+		else if (currentCommand.startsWith("skill"))
+		{
+			final String groupType = st.nextToken();
+			final String schemeName = st.nextToken();
+			final int skillId = Integer.parseInt(st.nextToken());
+			final int page = Integer.parseInt(st.nextToken());
+			final List<Integer> skills = SchemeBufferTableCustom.getInstance().getScheme(player.getObjectId(), schemeName);
+			if (currentCommand.startsWith("skillselect") && !schemeName.equalsIgnoreCase("none"))
+			{
+				if (skills.size() < player.getMaxBuffCount())
+				{
+					skills.add(skillId);
+				}
+				else
+				{
+					player.sendMessage("This scheme has reached the maximum amount of buffs.");
+				}
+			}
+			else if (currentCommand.startsWith("skillunselect"))
+			{
+				skills.remove(Integer.valueOf(skillId));
+			}
+			
+			showEditSchemeWindow(player, groupType, schemeName, page);
+		}
+		else if (currentCommand.startsWith("createscheme"))
+		{
+			try
+			{
+				final String schemeName = st.nextToken().trim();
+				if (schemeName.length() > 14)
+				{
+					player.sendMessage("Scheme's name must contain up to 14 chars.");
+					return;
+				}
+				// Simple hack to use spaces, dots, commas, minus, plus, exclamations or question marks.
+				if (!Util.isAlphaNumeric(schemeName.replace(" ", "").replace(".", "").replace(",", "").replace("-", "").replace("+", "").replace("!", "").replace("?", "")))
+				{
+					player.sendMessage("Please use plain alphanumeric characters.");
+					return;
+				}
+				
+				final Map<String, List<Integer>> schemes = SchemeBufferTableCustom.getInstance().getPlayerSchemes(player.getObjectId());
+				if (schemes != null)
+				{
+					if (schemes.size() == Config.BUFFER_MAX_SCHEMES_CUSTOM)
+					{
+						player.sendMessage("Maximum schemes amount is already reached.");
+						return;
+					}
+					
+					if (schemes.containsKey(schemeName))
+					{
+						player.sendMessage("The scheme name already exists.");
+						return;
+					}
+				}
+				
+				SchemeBufferTableCustom.getInstance().setScheme(player.getObjectId(), schemeName.trim(), new ArrayList<>());
+				showGiveBuffsWindow(player);
+			}
+			catch (Exception e)
+			{
+				player.sendMessage("Scheme's name must contain up to 14 chars.");
+			}
+		}
+		else if (currentCommand.startsWith("deletescheme"))
+		{
+			try
+			{
+				final String schemeName = st.nextToken();
+				final Map<String, List<Integer>> schemes = SchemeBufferTableCustom.getInstance().getPlayerSchemes(player.getObjectId());
+				if ((schemes != null) && schemes.containsKey(schemeName))
+				{
+					schemes.remove(schemeName);
+				}
+			}
+			catch (Exception e)
+			{
+				player.sendMessage("This scheme name is invalid.");
+			}
+			showGiveBuffsWindow(player);
+		}
+		
+		super.onBypassFeedback(player, command);
+	}
+	
+	@Override
+	public String getHtmlPath(int npcId, int value)
+	{
+		String filename = "";
+		if (value == 0)
+		{
+			filename = Integer.toString(npcId);
+		}
+		else
+		{
+			filename = npcId + "-" + value;
+		}
+		return "data/html/clanHallManager/SchemeBuffer/" + filename + ".htm";
+	}
+	
+	/**
+	 * Sends an html packet to player with Give Buffs menu info for player and pet, depending on targetType parameter {player, pet}
+	 * @param player : The player to make checks on.
+	 */
+	private void showGiveBuffsWindow(PlayerInstance player)
+	{
+		final StringBuilder sb = new StringBuilder(200);
+		final Map<String, List<Integer>> schemes = SchemeBufferTableCustom.getInstance().getPlayerSchemes(player.getObjectId());
+		if ((schemes == null) || schemes.isEmpty())
+		{
+			sb.append("<font color=\"LEVEL\">You haven't defined any scheme.</font>");
+		}
+		else
+		{
+			for (Map.Entry<String, List<Integer>> scheme : schemes.entrySet())
+			{
+				final int cost = getFee(scheme.getValue());
+				StringUtil.append(sb, "<font color=\"LEVEL\">", scheme.getKey(), " [", scheme.getValue().size(), " / ", player.getMaxBuffCount(), "]", ((cost > 0) ? " - cost: " + StringUtil.formatNumber(cost) : ""), "</font><br1>");
+				StringUtil.append(sb, "<a action=\"bypass -h npc_%objectId%_givebuffs;" + scheme.getKey() + ";" + cost + "\">Use on Me</a>&nbsp;|&nbsp;");
+				StringUtil.append(sb, "<a action=\"bypass -h npc_%objectId%_givebuffs;" + scheme.getKey() + ";" + cost + ";pet\">Use on Pet</a>&nbsp;|&nbsp;");
+				StringUtil.append(sb, "<a action=\"bypass -h npc_%objectId%_editschemes;Buffs;" + scheme.getKey() + ";1\">Edit</a>&nbsp;|&nbsp;");
+				StringUtil.append(sb, "<a action=\"bypass -h npc_%objectId%_deletescheme;" + scheme.getKey() + "\">Delete</a><br>");
+			}
+		}
+		
+		final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
+		html.setFile(getHtmlPath(getNpcId(), 1));
+		html.replace("%schemes%", sb.toString());
+		html.replace("%max_schemes%", Config.BUFFER_MAX_SCHEMES_CUSTOM);
+		html.replace("%objectId%", getObjectId());
+		player.sendPacket(html);
+	}
+	
+	/**
+	 * This sends an html packet to player with Edit Scheme Menu info. This allows player to edit each created scheme (add/delete skills)
+	 * @param player : The player to make checks on.
+	 * @param groupType : The group of skills to select.
+	 * @param schemeName : The scheme to make check.
+	 * @param page The page.
+	 */
+	private void showEditSchemeWindow(PlayerInstance player, String groupType, String schemeName, int page)
+	{
+		final NpcHtmlMessage html = new NpcHtmlMessage(getObjectId());
+		final List<Integer> schemeSkills = SchemeBufferTableCustom.getInstance().getScheme(player.getObjectId(), schemeName);
+		html.setFile(getHtmlPath(getNpcId(), 2));
+		html.replace("%schemename%", schemeName);
+		html.replace("%count%", schemeSkills.size() + " / " + player.getMaxBuffCount());
+		html.replace("%typesframe%", getTypesFrame(groupType, schemeName));
+		html.replace("%skilllistframe%", getGroupSkillList(player, groupType, schemeName, page));
+		html.replace("%objectId%", getObjectId());
+		player.sendPacket(html);
+	}
+	
+	/**
+	 * @param player : The player to make checks on.
+	 * @param groupType : The group of skills to select.
+	 * @param schemeName : The scheme to make check.
+	 * @param page The page.
+	 * @return a String representing skills available to selection for a given groupType.
+	 */
+	private String getGroupSkillList(PlayerInstance player, String groupType, String schemeName, int page)
+	{
+		// Retrieve the entire skills list based on group type.
+		List<Integer> skills = SchemeBufferTableCustom.getInstance().getSkillsIdsByType(groupType);
+		if (skills.isEmpty())
+		{
+			return "That group doesn't contain any skills.";
+		}
+		
+		// Calculate page number.
+		final int max = Util.countPagesNumber(skills.size(), PAGE_LIMIT);
+		if (page > max)
+		{
+			page = max;
+		}
+		
+		// Cut skills list up to page number.
+		skills = skills.subList((page - 1) * PAGE_LIMIT, Math.min(page * PAGE_LIMIT, skills.size()));
+		
+		final List<Integer> schemeSkills = SchemeBufferTableCustom.getInstance().getScheme(player.getObjectId(), schemeName);
+		final StringBuilder sb = new StringBuilder(skills.size() * 150);
+		int row = 0;
+		for (int skillId : skills)
+		{
+			sb.append(((row % 2) == 0 ? "<table width=\"280\" bgcolor=\"000000\"><tr>" : "<table width=\"280\"><tr>"));
+			if (skillId < 100)
+			{
+				if (schemeSkills.contains(skillId))
+				{
+					StringUtil.append(sb, "<td height=40 width=40><img src=\"icon.skill00", skillId, "\" width=32 height=32></td><td width=190>", SkillTable.getInstance().getSkill(skillId, 1).getName(), "<br1><font color=\"B09878\">", SchemeBufferTableCustom.getInstance().getAvailableBuff(skillId).getDescription(), "</font></td><td><button action=\"bypass -h npc_%objectId%_skillunselect;", groupType, ";", schemeName, ";", skillId, ";", page, "\" width=32 height=32 back=\"L2UI_CH3.mapbutton_zoomout2\" fore=\"L2UI_CH3.mapbutton_zoomout1\"></td>");
+				}
+				else
+				{
+					StringUtil.append(sb, "<td height=40 width=40><img src=\"icon.skill00", skillId, "\" width=32 height=32></td><td width=190>", SkillTable.getInstance().getSkill(skillId, 1).getName(), "<br1><font color=\"B09878\">", SchemeBufferTableCustom.getInstance().getAvailableBuff(skillId).getDescription(), "</font></td><td><button action=\"bypass -h npc_%objectId%_skillselect;", groupType, ";", schemeName, ";", skillId, ";", page, "\" width=32 height=32 back=\"L2UI_CH3.mapbutton_zoomin2\" fore=\"L2UI_CH3.mapbutton_zoomin1\"></td>");
+				}
+			}
+			else if (skillId < 1000)
+			{
+				if (schemeSkills.contains(skillId))
+				{
+					StringUtil.append(sb, "<td height=40 width=40><img src=\"icon.skill0", skillId, "\" width=32 height=32></td><td width=190>", SkillTable.getInstance().getSkill(skillId, 1).getName(), "<br1><font color=\"B09878\">", SchemeBufferTableCustom.getInstance().getAvailableBuff(skillId).getDescription(), "</font></td><td><button action=\"bypass -h npc_%objectId%_skillunselect;", groupType, ";", schemeName, ";", skillId, ";", page, "\" width=32 height=32 back=\"L2UI_CH3.mapbutton_zoomout2\" fore=\"L2UI_CH3.mapbutton_zoomout1\"></td>");
+				}
+				else
+				{
+					StringUtil.append(sb, "<td height=40 width=40><img src=\"icon.skill0", skillId, "\" width=32 height=32></td><td width=190>", SkillTable.getInstance().getSkill(skillId, 1).getName(), "<br1><font color=\"B09878\">", SchemeBufferTableCustom.getInstance().getAvailableBuff(skillId).getDescription(), "</font></td><td><button action=\"bypass -h npc_%objectId%_skillselect;", groupType, ";", schemeName, ";", skillId, ";", page, "\" width=32 height=32 back=\"L2UI_CH3.mapbutton_zoomin2\" fore=\"L2UI_CH3.mapbutton_zoomin1\"></td>");
+				}
+			}
+			else
+			{
+				if (schemeSkills.contains(skillId))
+				{
+					StringUtil.append(sb, "<td height=40 width=40><img src=\"icon.skill", skillId, "\" width=32 height=32></td><td width=190>", SkillTable.getInstance().getSkill(skillId, 1).getName(), "<br1><font color=\"B09878\">", SchemeBufferTableCustom.getInstance().getAvailableBuff(skillId).getDescription(), "</font></td><td><button action=\"bypass -h npc_%objectId%_skillunselect;", groupType, ";", schemeName, ";", skillId, ";", page, "\" width=32 height=32 back=\"L2UI_CH3.mapbutton_zoomout2\" fore=\"L2UI_CH3.mapbutton_zoomout1\"></td>");
+				}
+				else
+				{
+					StringUtil.append(sb, "<td height=40 width=40><img src=\"icon.skill", skillId, "\" width=32 height=32></td><td width=190>", SkillTable.getInstance().getSkill(skillId, 1).getName(), "<br1><font color=\"B09878\">", SchemeBufferTableCustom.getInstance().getAvailableBuff(skillId).getDescription(), "</font></td><td><button action=\"bypass -h npc_%objectId%_skillselect;", groupType, ";", schemeName, ";", skillId, ";", page, "\" width=32 height=32 back=\"L2UI_CH3.mapbutton_zoomin2\" fore=\"L2UI_CH3.mapbutton_zoomin1\"></td>");
+				}
+			}
+			
+			sb.append("</tr></table><img src=\"L2UI.SquareGray\" width=277 height=1>");
+			row++;
+		}
+		
+		// Build page footer.
+		sb.append("<br><img src=\"L2UI.SquareGray\" width=277 height=1><table width=\"100%\" bgcolor=000000><tr>");
+		if (page > 1)
+		{
+			sb.append("<td align=left width=70><a action=\"bypass -h npc_" + getObjectId() + "_editschemes;" + groupType + ";" + schemeName + ";" + (page - 1) + "\">Previous</a></td>");
+		}
+		else
+		{
+			sb.append("<td align=left width=70>Previous</td>");
+		}
+		
+		sb.append("<td align=center width=100>Page " + page + "</td>");
+		if (page < max)
+		{
+			sb.append("<td align=right width=70><a action=\"bypass -h npc_" + getObjectId() + "_editschemes;" + groupType + ";" + schemeName + ";" + (page + 1) + "\">Next</a></td>");
+		}
+		else
+		{
+			sb.append("<td align=right width=70>Next</td>");
+		}
+		
+		sb.append("</tr></table><img src=\"L2UI.SquareGray\" width=277 height=1>");
+		return sb.toString();
+	}
+	
+	/**
+	 * @param groupType : The group of skills to select.
+	 * @param schemeName : The scheme to make check.
+	 * @return a string representing all groupTypes available. The group currently on selection isn't linkable.
+	 */
+	private static String getTypesFrame(String groupType, String schemeName)
+	{
+		final StringBuilder sb = new StringBuilder(500);
+		sb.append("<table>");
+		
+		int count = 0;
+		for (String type : SchemeBufferTableCustom.getInstance().getSkillTypes())
+		{
+			if (count == 0)
+			{
+				sb.append("<tr>");
+			}
+			
+			if (groupType.equalsIgnoreCase(type))
+			{
+				sb.append("<td width=65>" + type + "</td>");
+			}
+			else
+			{
+				sb.append("<td width=65><a action=\"bypass -h npc_%objectId%_editschemes;" + type + ";" + schemeName + ";1\">" + type + "</a></td>");
+			}
+			
+			count++;
+			if (count == 4)
+			{
+				sb.append("</tr>");
+				count = 0;
+			}
+		}
+		
+		if (!sb.toString().endsWith("</tr>"))
+		{
+			sb.append("</tr>");
+		}
+		
+		sb.append("</table>");
+		
+		return sb.toString();
+	}
+	
+	/**
+	 * @param list : A list of skill ids.
+	 * @return a global fee for all skills contained in list.
+	 */
+	private static int getFee(List<Integer> list)
+	{
+		if (Config.BUFFER_STATIC_BUFF_COST > 0)
+		{
+			return list.size() * Config.BUFFER_STATIC_BUFF_COST;
+		}
+		
+		int fee = 0;
+		for (int sk : list)
+		{
+			fee += SchemeBufferTableCustom.getInstance().getAvailableBuff(sk).getPrice();
+		}
+		
+		return fee;
+	}
+}
\ No newline at end of file

Swarlog

Posiblemente tengas que asignar la id del npc buffer a la clase manager de los clan hall o al menos asignársela.

Veo que usar "L2JMobius". Si usas la versión privada, lo ideal seria que ellos te brinden soporte.

Saludos ^^