Jump to content


Legendary Member
  • Posts

  • Joined

  • Last visited

  • Days Won

  • Feedback


melron last won the day on October 6

melron had the most liked content!

About melron

Contact Methods

  • Website URL
  • Skype
    melron mxc

Profile Information

  • Current Mood
  • Gender
  • Country
  • Location
    Valley of Saints

Recent Profile Visitors

24,251 profile views

melron's Achievements

  1. elif event == "30620-7.htm" and st.getQuestItemsCount(FRUIT_BASKET) == 1 : st.takeItems(FRUIT_BASKET,1) if (random.randint(1, 100) < 70): st.giveItems(ADENA,500000) else: st.giveItems(MASK,1) st.unset("cond") st.playSound("ItemSound.quest_finish") st.exitQuest(1) return htmltext import random
  2. Mods are mods. You share them and then the receiver can change anything. I'm just pointing out some things not for the mod itself, but for a general purpose. Not a problem at all, melron#5110
  3. Im just 'hearing' the phrase "farm" and im expecting exp,sp and some rewards 😛 Well, my purpose wasn't to 'change' your check. Its indeed the same result but im using meetTheConditions at every time i need to reward someone and also im using the method for every reward. Check my code again. As i said with an example, you can add multiple checks and conditions for 1 item reward. As it is now, except that there isn't any check on the reward state, but lets say we add it. It should use the 'same' check for all your rewards. With custom classes, you have the ability to create the necessary check for any item
  4. Thanks for your share! The main concept for idle farm is the exp,sp. Rewards can be added also by some specific conditions, but in anycase it should't be as a main reward (in my pov). About the code structure, it would be easier/correct to use an interface to build your xp/sp/rewards with their name as a tag. Your _itemsList array should be refactored and also your thought about IdleItem class (by naming view policy, im expecting data of an item (id,count) with the name IdleItem), it could be an intintholder instead. You can completely remove the class Engine and instead, implement the Runnable class at your IdleFarmManager . It would generate the overriden method 'run'. A security thing now, you are correctly checking for join conditions in order to add someone to your idle farm list, but you are not checking anything up on the reward state. Considering the fact that this feature could be used for low rate servers too, they can easily cheat even if the 1st join condition have the peace zone check.. There are numerous of things that players can think about to 'hack' it. They have recall skills, gotolove or 1000 other things that you can't imagine right now. Also, another benefit that you would get by checking some conditions up on the reward state is that some rewards may need some extra conditions to be applied. For example, you can add an +1 A grade enchant to rhand only if the player is 80 level, have A grade weapon equipped with enchant level < 3 and 0 EAW items found on inventory/warehouse. (Just an example). In that case, you need a different check conditions for that. My personal opinion for this code is to create an interface package net.sf.l2j.gameserver.custom.idlefarm.rewards; import java.time.temporal.ValueRange; import net.sf.l2j.gameserver.enums.ZoneId; import net.sf.l2j.gameserver.model.actor.Player; import net.sf.l2j.gameserver.model.holder.IntIntHolder; /** * @author Melron */ public interface IIdleFarmReward { public boolean meetTheConditions(Player player); public int getChance(); public IntIntHolder[] getItemRewards(); public int getExp(int playerLevel); public int getSp(int playerLevel); default boolean levelIsBetween(Player player, int min, int max) { return ValueRange.of(min, max).isValidValue(player.getStatus().getLevel()); } default boolean isInTown(Player player) { return player.isInsideZone(ZoneId.PEACE); } } and then start creating your classes by giving the correct name. Example, NewbiesReward/AdvancedReward. etc. An example for NewbiesReward : package net.sf.l2j.gameserver.custom.idlefarm.rewards.type; import net.sf.l2j.commons.random.Rnd; import net.sf.l2j.gameserver.custom.idlefarm.rewards.IIdleFarmReward; import net.sf.l2j.gameserver.model.actor.Player; import net.sf.l2j.gameserver.model.holder.IntIntHolder; /** * @author Melron */ public class NewbiesReward implements IIdleFarmReward { private static final int MIN_LEVEL = 45; private static final int MAX_LEVEL = 67; private static final IntIntHolder[] ITEM_REWARDS = new IntIntHolder[] { new IntIntHolder(57, 5_000_000), new IntIntHolder(57, 2_000_000), }; @Override public boolean meetTheConditions(Player player) { return isInTown(player) && levelIsBetween(player, MIN_LEVEL, MAX_LEVEL); } @Override public int getChance() { return 70; } @Override public IntIntHolder[] getItemRewards() { return ITEM_REWARDS; } @Override public int getExp(int playerLevel) { final int baseValue = playerLevel * 1_000_000; return Rnd.get(baseValue, baseValue * 2); } @Override public int getSp(int playerLevel) { final int baseValue = playerLevel * 500_000; return Rnd.get(baseValue, baseValue * 2); } } for Advanced: package net.sf.l2j.gameserver.custom.idlefarm.rewards.type; import net.sf.l2j.commons.random.Rnd; import net.sf.l2j.gameserver.custom.idlefarm.rewards.IIdleFarmReward; import net.sf.l2j.gameserver.model.actor.Player; import net.sf.l2j.gameserver.model.holder.IntIntHolder; /** * @author Melron */ public class AdvancedReward implements IIdleFarmReward { private static final int MIN_LEVEL = 76; private static final int MAX_LEVEL = 80; private static final IntIntHolder[] REWARDS = new IntIntHolder[] { new IntIntHolder(961, 1), // EWS new IntIntHolder(1540, 100), // QHP }; @Override public boolean meetTheConditions(Player player) { return isInTown(player) && levelIsBetween(player, MIN_LEVEL, MAX_LEVEL); } @Override public int getChance() { return 2; } @Override public IntIntHolder[] getItemRewards() { return REWARDS; } @Override public int getExp(int playerLevel) { final int baseValue = playerLevel * 5_000_000; return Rnd.get(baseValue, baseValue * 2); } @Override public int getSp(int playerLevel) { final int baseValue = playerLevel * 2_500_000; return Rnd.get(baseValue, baseValue * 2); } } You can specify whatever you need on the classes and play with meetConditions method to allow the player to get some rewards. (The exp,sp calcs are random). If you want 1 condition to be checked after and a chance check and assuming you have set all your rewards on a Set or something simillar, for (IIdleFarmReward reward : REWARDS) { if (reward.meetTheConditions(player)) { player.getStatus().addExp(reward.getExp(player.getStatus().getLevel())); player.getStatus().addSp(reward.getSp(player.getStatus().getLevel())); for (IntIntHolder rewardHolder : reward.getItemRewards()) if (Rnd.get(100) <= reward.getChance()) player.addItem("Idle Farm", rewardHolder.getId(), rewardHolder.getValue(), null, true); } } But i insist that if you edit a bit my way, you can achieve some cool things for them 🙂
  5. Edit: All captchas with classic math question or "click the correct icon", are bypassable
  6. Not bad at all but, you have to change a bit the 'whole' system. Make it a bit easier...
  7. First of all an offtopic reply: You did remind me the base version of my coupon manager 🤪 Now, lets focus on your idea. Not bad at all, something new/fresh that in my pov, can be used and run with a simple npc that would ask for a price to play a new round. I'm also expecting a better reward when i got 2/3 or 3/3 success hits. The reward can simply be multiplied in that case (if the id,qnt have to be constants). Now lets focus on your code. You have to care about your bypasses. There are missing important checks for numerous suspicion actions. The code inside of your if statement if(command.startsWith("_menuMinesSelect")){ ... } does not have any protection and it can be easily bypassed and request full rewards with a 50% chance at all. The reward action should be handled when the 'change icon' action take place. Atm, you have 2 different cases while the imporant one is located at the bypass that i mentioned. As it is now, it looks like that you can succeed the box without reward but also, the opossite. You did care about the ConcurrentException inside of MinesManager but you didnt at the MinesEvent (which is created with an arraylist) You have to debug your code for any possible mistake that you 'forgot' to fix up on the creation state. For example, something is wrong here: case 0: Broadcast.announceToOnlinePlayers("[EVENT] ~ [Mines] Registrations closed.", true); if(MinesEvent.getInstance().getTotalPlayers() < 1) { Broadcast.announceToOnlinePlayers("[EVENT] ~ [Mines] Cancelled due to luck of participants.", true); }else { MinesEvent.getInstance().start(); } setStarted(false); break; You checking the total players count to decide if you have to start the event or abandon it but just after your decision, there is: setStarted(false); Not a big deal at all but i think you got my point. I'm not seeing somewhere this boolean how and when is taking place but probably, is on the file you are not posting. isStarted() Generally, take care about naming policy (with proper lower/upper case and all), delete useless lines if(command.startsWith("_menuMinesSelect")){ String selected = ""; // Where this variable is taking place? String cmdContent = st.nextToken(); // Where also this variable taking place? int position = Integer.valueOf(st.nextToken()); int chance = Integer.valueOf(st.nextToken()); Mines newMine = MinesManager.getInstance().getMine(activeChar.getObjectId()); if(chance > 50) newMine.soloRewards(activeChar); newMine.selectedBox(position); newMine.minesWindow(activeChar); Read the java 8 features and get into stream . The addition of the Stream was one of the major features added to Java 8. Don't miss it. For example, this code: public class MineBox{ public int position; public int chance; public boolean selected; public String content; } public void feedList(){ for(int i=0; i < 30; i++){ MineBox bx = new MineBox(); bx.position = i; bx.chance = Rnd.get(100); bx.selected = false; _boxs.add(bx); } } Can be improved to this one: public class MineBox { public final int position; public final int chance = Rnd.get(100); public boolean selected = false; public String content; public MineBox(int pos) { position = pos; _boxs.add(this); } } public final void feedList() { IntStream.of(30).forEach(MineBox::new); } The only real problem impacting the stability is the ConcurrentException. Use ConcurrentHashMap.newKeySet() to handle it properly. All the other changes are about readability, performance and optimization. I like you and i admire your effort. Keep sharing
  8. Search again at systemmsg-e.dat.
  9. A Java app with jni implementation to gain access in native libraries would work on every l2 server with or without protection
  10. Well i'm ignorant with client modifications (except some easy tasks) so i dont know how much time this map needs to be created. P.S Does a map like this, consumes 5-6 hours ?
  11. I need to reply with an offtopic post. A full detailed jserver creation request from a client would probably not cost more than 200E. Fun fact1: 1 map equals to 500+ E. Fun fact2: this map can be stolen from anyone who playing that server. Fun fact3: the original map creator is actually stolen the original files to create the 'Fun fact 1' Fun fact4: the 'scammer' named scammer because he edited a scammed file that it was located at scammed files. Moral Lesson: Be l2jdev.
  12. If you plan to create something based on this poll then don't. I'm expecting arround 10 votes. It will be terrible mistake if you go based on those votes because 10 votes (even 20) is not the thing you looking for. Just go arround at every l2 vote site and see the top servers, see rates, play some of them to get ideas (about custom equipment etc) and then create your plan with a common goal the logic. -Voted and good luck.
  13. There are plenty of questions that someone could ask you to understand what exactly you need. The explanation is not so detailed. Can you post your code to see how you get the data in your list? If you have a custom manager to handle this action, you probably need a Map and not an arraylist. If you need to use the ZoneManager which is the 'correct way' to handle this, you have to follow the Zake's example with some additions like: ZoneManager.getInstance().getZone(boss,BossZone.class).getRandomLocation();
  • 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 Disbaled AdBlock