Jump to content

fixthissite

Trade With Caution
  • Posts

    364
  • Joined

  • Last visited

  • Days Won

    2
  • Feedback

    0%

Everything posted by fixthissite

  1. Rather than manually typing out the experience table, you can use the formula Jagex uses to calculate it dynamically. Here's a little snippit if you want to use it in the future: public static int[] createTable(int level) { int[] table = new int[level]; for(int i=1, b=0; i < level; b += i + 300 * Math.pow(2, i / 7d), table[i] = i == 99? 200000000 : b/4, i++); return table; }
  2. If it weren't for competition, the gaming industry will be no where near where it is today. We wouldn't have Sonic if it weren't for Sega wanting to compete with Mario. We wouldn't have pushed towards 3d as we did if it weren't for the bit wars.Competition drives innovation.
  3. Java would never remove primitives. Even with Java 9's value type, which lowers the footprint of object creation, they will not be removed. It would break too much code. Check this out
  4. I understand why you prefer it that way, especially seeing how you're already a scripter (probably familiar with that style). But for a beginner scripter, or even a beginner programmer, it could be quite easy to forget to add a condition to getState() or possibly forget to call the "brain" methods (I call em behavioral methods) in the onLoop. The style I proposed doesn't require the scripter to focus on 4 sections independently (the decisions, the decision makers, the executor and the brain). After setting up the onLoop method, they are forced to implement everything that's needed (decision, decision maker, the brain) as soon as they create a new decision. It's nearly impossible to forget to add a condition with this style, since everytime you create a new decision, a compilation error occurs if you forget to create the "decision maker" or the "brain" for a decision. In the functional style, if you were to forget something, you wouldn't realize you accidentally left something out until after you've ran the script. Compilation errors are always preferred to runtime errors, since they inform you of a problem right away. As the script grows in size, there's more potential to mess up if the code doesn't enfornce such rules (every state must have a condition and behavior)
  5. You are doing !cow.isVisible before checking if cow is null. Change if(!cow.isVisible() || cow == null) to if(cow == null || !cow.isVisible())
  6. What does this have to do with this thread?I suggest creating your own thread for this, or better yet, read the tutorials (I have a tutorial on creating a GUI for settings)
  7. First, I'd like to say that you shouldn't decide that a coding style is good for beginners soley due to the fact that it uses primitive coding techniques (which programmers tend to learn at an early stage). Code which requires to to focus on only one thing, rather than changing 3 different things to implement what you want, is good code for a beginner. To give you options, there's another way of handling the states, which I find to be a lot cleaner: class MyScript extends Script { public int onLoop() { for(State state : State.values()) if(state.canProcess(this)) state.process(this); } enum State { DROP { boolean canProcess(MyScript script) { return script.inventory.contains(...); } void process(MyScript script) { script.inventory.drop(...); } }, STEAL { boolean canProcess(MyScript script) { //... } void process(MyScript script) { //... } }; abstract void process(MyScript script); abstract void canProcess(MyScript script); } } I understand a few people aren't syntax savvy, and would love to point and yell at my code. Please read below first.. In the functional style code (creating getState() method and what not), there's quite some room to mess up. 1. Forget to specify the state condition in getState() 2. Forget to account for the state in onLoop 3. Forget to call the behavioral methods in onLoop 4. Forgetting break statements With this new, object oriented way, you no longer need to worry about the onLoop method (once you have created it, that is); it will not change, so you won't forget to account for states. To create a new state, you simply create a new enum value (with a body to declare methods). Each enum value is forced to declare a conditional method and a behavioral method, so the user will not forget to account for those. Rather than being required to focus on onLoop() and getState(), all you need to do (literally) is define your state. Adding states is easy as pie.
  8. Get ready for a long post, buddy. It depends. The easiest way to handle this would be to hardcode the settings into the DefaultAPI and pass that around as you've mentioned, more preferably creating a Settings type to decompose the DefaultAPI: class MySettings { private int logId; public int getLogId() { return logId; } public void setLogId(int id) { logId = id; } } class DefaultAPI extends API { private MySettings settings; public void setSettings(MySettings settings) { this.settings = settings; } public MySettings settings() { return settings; } } You could then create an instance of MySettings whenever the user clicks the "start" button on your GUI, passing it to the API. The code above does not account for (im)mutability; it does what you mention, but it's decomposed for easy maintenence. It allows you to adjust the settings at just about anytime, and you can modify the settings in different ways. So now comes the encapsulation, which strongly depends on how you want this to function. If the settings are handled at the start of your script, and should not be modified afterwards First, remove the ability to modify the settings property in DefaultAPI. You can do this by creating the API when you create the user clicks the "start" button to start the script. The idea is that the GUI handles the "arguments" of the script (similar to how the VM has VM arguments and command-line programs have command-line arguments): class GUI { private Object lock = new Object(); //used for waiting public DefaultAPI create() { GUI gui = new GUI(); gui.setVisible(true); //halt thread until user clicks "start" button try { synchronized(lock) { lock.wait(); } } catch(InterruptedException e) { //... } MySettings settings = ...; DefaultAPI api = new DefaultAPI(settings); return api; } private ActionListener listener = event -> { synchronized(lock) { lock.notify(); } }; } class DefaultAPI { private MySettings settings; public DefaultAPI(MySettings settings) { this.settings = settings; } public MySettings settings() { return settings; } //can no longer switch instance of Settings } class MyScript extends Script { void onStart() { DefaultAPI api = GUI.create(); //pass api to nodes } } So once you've passed the API the settings, it can not be modified by passing the API a new MySettings instance. Although, nodes can still adjust the settings through the setter methods of MySettings. For situations like this, where we want to be able to optionally set values on creation, but prevent them from being modified after creation, we would use the builder pattern: class MySettings { private int logId; private MySettings(Builder builder) { logId = builder.logId; } public int getLogId() { return logId; } //no mutators; cannot adjust settings after creating public static final class Builder { private int logId; public Builder setLogId(int id) { logId = id; return this; } //other builder methods go here... public MySettings build() { return new MySettings(this); } } } When you create the API in GUI.create(), simply use the builder: MySettings settings = new MySettings.Builder() .setLogId(/* grab from component */) .build(); DefaultAPI api = new DefaultAPI(settings); In this situation, a builder is an overkill; you could simply pass the logId to the constructor. But as the amount of settings options increase, so will the amount of constructor arguments. If you have 10 settings, all which are of type int, it could easily confuse the developer, which is why a builder is preferred. Not sure why theres no support for this in the API already. If I were you guys, I'd request more support for things like this (GUI, script settings). Just to clear the air, it is prefered to use static getter/setters rather than accessing a static field directly. You can read more on my "Use Getter Methods, Not Public Fields" thread - the idea is to hide implementation details, allowing you to change how you store a property without breaking code that relies on it. As for using static getters/setters for this, it would make it a LOT easier. Although, when it comes to unit testing, difficulties arise (hard to isolate code that relies on global state). It could also make graphing your code a mess, with edges that fly all over the place. It's best to keep things as encapsulated as possible. Rather than accessing something globally (accessing a dependency globally), pass in the dependency through a method/constructor. This is called dependency injection, and makes code crazy easy to unit test. Don't do class MyClass { public void doSomething() { int answer = OtherClass.number + 5; } } Do class MyClass { public void doSomething(int number) { int answer = number + 5; } } Passing in the number when you call the method. Sorry for the long post, I like to be fluent.
  9. Never been to college, but I study a lot, and I feel it has more to do with how you use your time, rather than how much time you put in. It would probably be better to ask for study tips. I like knowledge, so I do personal studies (consider me a nerd). Through my studies, I have came up with a few tricks to decrease the amount of time I spend in a subject, while still learning a vast majority of it, which I'm sure that's something you'd be more interested in knowing First thing you gotta do is realize a few things: As I said before, I've never been to a physical college, but Coursera offers free online college courses, which is how I've came to realize most of the things I stated above. I really believe independent studies, along with a mentoring, is the best way to achieve knowledge. So, now for those tips.. Hope these tips help in your studies. Keep in mind, these are based on my experiences, so don't take it as complete fact; they are just things I seemed to have realized over the years.
  10. You asked me to take a look at your code, which I gave a small review here. I got on a computer and was able to run this, got an error right away: java.io.FileNotFoundException: gLEPkie8@4MCmCD.txt (The system cannot find the file specified) This is because you never check to see if the file has already been created; you assume the file already exists on my system, which it doesn't. You should be doing: File file = new File("gLEPkie8@4MCmCD.txt"); if(!file.exists()) file.createFile(); You aren't setting the location of your frame. Usually, people center it, although even that can cause problems (people not realizing they accidentally opened multiple windows). Try implementing JFrame#setLocationByPlatform(boolean) and tell me how you like it. I see you attempted to add a hints to your text field (shadowed text). The problem is, it doesn't have that "shadow" feel, and doesn't disappear when you click on the field. Here's a little class I built up, which supports hints: import java.awt.Color; import java.awt.event.FocusAdapter; import java.awt.event.FocusEvent; import javax.swing.JTextField; public class JHintedTextField extends JTextField { private String hintedText; private boolean hintDisplayed; public JHintedTextField(int columns, String hintedText) { super(columns); this.hintedText = hintedText == null ? "" : hintedText; addFocusListener(adapter); displayHint(hintedText); } public JHintedTextField(String hintedText) { this(0, hintedText); } private FocusAdapter adapter = new FocusAdapter() { public void focusGained(FocusEvent e) { if(hintDisplayed) removeHint(); } public void focusLost(FocusEvent e) { if(!hintDisplayed && getText().isEmpty()) displayHint(hintedText); } }; private void displayHint(String hint) { setText(hint); setForeground(Color.GRAY); hintDisplayed = true; } private void removeHint() { setText(""); setForeground(Color.BLACK); hintDisplayed = false; } } Rather than using whats referred to as a stream loop [while((line = in.readLine()) != null)] is redundant when using a BufferedReader ever since Java 8: BufferedReader reader = ...; reader.lines().forEach(line -> { ... }); I can add the same user/pass to the "Saved Passwords". You should instead be using some kind of Set to store your entries. It would also be better practice to combine the label and field into it's own panel (a new panel per entry), so you could add functionality such as right clicking an entry to remove it. As for the problem you told me earlier (preserving the state of a map between shutdowns of your app), here's a little example of storing a Map object onto your drive, then loading it back into memory: void saveObject(Map<String, String> map) throws IOException { ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("name.anyAbbreviation")); out.writeObject(map); } Map<String, String> loadObject() throws IOException, ClassNotFoundException { ObjectInputStream in = new ObjectInputStream(new FileInputStream("name.anyAbbreviation")); Map<String, String> m = (Map<String, String>) in.readObject(); return m; } Rather than using a map, though, you should create a new type, PasswordEntry, which contains the information for the entry (such as the name and password as you have now, but also things such as suggested expiration dates, date created, and possibly details about the account it's saved for such as "This is for a woodcutting account" or something"). I have to hop off the computer, but hopefully what I've said so far helped. I'm sure there's more that can be fixed up, so let me know if you want me to take another look once you've fixed it up a bit.
  11. Of course, why should I have thought OSBot was consistent? Silly me...
  12. Why wouldn't it? "Write once, run anywhere (assuming you have a JVM)" - Java
  13. Sounds like a job for serialization (preserve the state of an object after shutdown). Create an ObjectOutputStream and call writeObject, passing in the map as the parameter. You can then read it back in using an ObjectInputStream. This will prevent the need to read text from a file as you currently are. I'm not at a computer, so I can't run your app. But looking at the code, there are a few things you should do: 1. while (x < SliderT) { randomNum = rand.nextInt(random.length()); password += random.substring(randomNum, (randomNum + 1)); x++; } You should be using a StringBuilder for password. Right now, you are using String concatenation, which actually uses a StringBuilder under the hood (view the bytecode). The problem is, each time you do "+=", a new StringBuilder is created, which means you are creating a bunch of excess objects which may impact performance. You should instead do: StringBuilder password = new StringBuilder(); while(...) { ... password.append(random.substring(...)); ... } 2. Boolean Button1, Button3, Button4, Button5; Button1 = jToggleButton1.isSelected(); Button3 = jToggleButton3.isSelected(); Button4 = jToggleButton4.isSelected(); Button5 = jToggleButton5.isSelected(); I'd usually ask why you are declaring and assigning in different locations, but there is a bigger problem here: autoboxing. Unless this code was being called within a long running loop, it doesn't matter as much. But there's still no reason why you should be doing it. Don't use the Boolean reference type, use the boolean primitive type. Otherwise, you're basically doing Button5 = new Boolean(...); Creating excess objects that aren't needed. You would also be able to finally do if(!Button5) rather than if(Button5 == false). 3. if(jToggleButton4.isSelected()){ jToggleButton4.setText("ON"); } else { jToggleButton4.setText("OFF"); } Use a ternary: String text = jToggleButton4.isSelected() ? "ON" : "OFF"; jToggleButton4.setText(text); 4. Try to go through an replace all ActionListener anonymous classes with lambda expressions. This will reduce the amount of class files generated, reducing the amount of files needed to be loaded by a classloader. 5. p.removeAll(); p.repaint(); This shows me you have yet to understand the component system Swing provides you. I highly suggest taking a deeper look into it. You need to revalidate after affecting the component hierarchy (add/remove), not repaint. There are a few other things I wanted to note down, but my phone is dying so I'ma have to come back to this. If you'd like me to post this on your code thread, let me know and I'll transfer it over.
  14. After giving another look, it seems you're trying to add components to an already visible panel. I had a hard time understanding your problem, but forgetting to validate() a container (which is already visible) after adding components to it will result in an empty container: "Layout-related changes, such as setting the bounds of a component, or adding a component to the container, invalidate the container automatically" If I'm understanding this correctly, you want to iterate through the entries of a map, and display a label and field for each entry. Here's a little example (which performs what you want) that shows what I'm referring to about validating. Simply uncomment the pack() to make the code below work: public class Demo { public static void main(String[] args) { Demo demo = new Demo(); EventQueue.invokeLater(demo::init); } void init() { Map<String, String> map = createMap(); JFrame frame = new JFrame(); frame.setLayout(new FlowLayout()); frame.setDefaultCloseOperation(3); addComponentsTo(frame, map); frame.pack(); frame.setVisible(true); } void addComponentsTo(JFrame frame, Map<String, String> map) { JPanel panel = new JPanel(); GridLayout layout = new GridLayout(0, 2); layout.setHgap(0); panel.setLayout(layout); JButton button = new JButton("..."); button.addActionListener(event -> { map.forEach((key, value) -> { JLabel label = new JLabel(key); JTextField field = new JTextField(value); panel.add(label); panel.add(field); //frame.pack(); }); }); frame.add(button); frame.add(panel); } Map<String, String> createMap() { Map<String, String> map = new TreeMap<>(); map.put("First", "FirstItem"); map.put("Second", "SecondItem"); map.put("Third", "ThirdItem"); return map; } } I used a TreeMap to retain order in the map. Although "validate()" will display the items, it will not size the frame to fit them. You should instead "pack()" as I did, which validates the entire component hierarchy.
  15. 1) Not enough code, and please elaborate a little more on what you mean (when does it appear? is it consistent behavior, as in does it happen every time?) 2) Add the panel to a JScrollPane Is there a reason why you're casting so much? Why are you referencing the keySet using the Object type, rather than Set<String>?
  16. I did. We found out that1. I forgot to set the retention policy for the annotations. For some reason, AIDE (my mobile IDE) doesn't care for the retention of annotations 2. He was attempting to use the two systems (link and fragment) as one, which I have mentioned does not work with the first release. I created an integrated version, but apparently I forgot to release it. I'll be revamping this entire thread, with a working, cleaner version of these systems that wirk seemlessly together. Sorry for the inconvienence people. Take this as an example of what not to do when releasing snippits :P
  17. Please meet me in the Chatbox and I'll give you my skype there
  18. This is the version I actually tested:http://pastebin.com/ukJPBLhA You're going to need to add the constructor which access the MethodProvider, then go down to getConstructor().newInstance() and pass it to the newInstace() method. The previous pastebin I sent you was me trying to apply the changes from the version I actually tested to the version with the MethodProvider already implemented. This is the one I have ran, which I know works. You're going to have to fix up the imports, though. The other version should have worked after the changes, though. Are you sure you called "initCurrentSettings" in onStart()? And you've change nodeSet.get(node) to currentNodeSet = nodeSet.get(node) in initCurrentSettings, yeah? currentNodeSet should not be null. If it is, that means the value isn't in the map, which I've added to the map in the add method [nodeSet.put(node, linkNodes(...))]. I tried messaging you, but it keeps on saying the site lost connection. Idk what's wrong, I'ma have to report it.
  19. True champ For the first one, we need to check if the array passed in (through the parameters) has at least 1 value. Change linkedNodes.length (in the original code, not the one you modified) to linkedNodeTypes.length.The second one, you should actually be initializing the currentNodeSet variable with the value obtained from nodeSet.get(node). Change that line to currentNodeSet = nodeSet.get(node); For the last one, replace put(nodeType, linkNodes(...)) with put(node, linkNodes(...)) I promise these kinds difficulties will not appear in future guides/snippits. I'm not at home right now, so I can't do much when it comes to running the code I release on here, and if I only released these things while I was on a computer, I'd never get to it (too many other things to focus on while on a computer). But I will make sure others have tested before releasing anything in the future. As for the other guy implementing it right, keep in mind that not everyone is at the same programming skill level. He probably saw the problems himself and fixed it up
  20. Didn't realize my pm system was disabled. I'm not sure how to re-enable it. I'll send you a message (which hopefully you could reply to).I couldn't run the final pastebin I uploaded (not at a computer, so I removed references of OSBot before testing), but I ran a mock version of it which worked fine. Hopefully I didn't mess anything up while re-implementing the OSBot stuff (the MethodProvider reference)
  21. After taking another look at the code, I've made a fatal mistake. The nodeSet map is mapping class types to node: Map<Class<? extends Node>, Node[]> nodeSet; //should be named nodeSetMap But in initCurrentSet, I told you to do nodeSet.get(node), when node is an instance of the class, not the class type (since allNodes.values() returns a Set<Node> and not a Set<Class<? extends Node>>). Map<Class<? extends Node>, Node> allNodes; for(Node node : allNodes.values()) { if(node.canProcess()) { currentNodeSet = nodeSet.get(node); break; } } What I told you before (the code I just showed) should have actually generated a compiler error. On top of that, I found a few little mistakes I didn't tend to (such as validating that you actually specified nodes in @Linked), so try this out: http://pastebin.com/QHTEg53H It's still messy. The fixes I added were quick fixes (making the design look even messier), but I'm cleaning this up as we speak, since apparently a re-upload is much needed. Let me know if the new LinkerManager works for you! And thank you for finding these problems for me. As I've said before, I've never actually ran this. I released it shortly after the person who requested it told me he got it working (with a few minor tweaks). Never release without testing X_X
  22. Seems I forgot to set the initial "currentNodeSet". I uploaded this without testing, which seems to always be a problem. I'll make sure to test anything I release in the future To fix this, you're going to need to find a set that best fits your bot when it starts. You can do this in a few different ways. I recommend setting it in onStart, right before continuing to onLoop: void onStart() { manager.add(...); manager.add(...); manager.initCurrentSet(); } Within the Manager class, you would add public void initCurrentSet() { for(Node node : allNodes.values()) { if(node.canProcess()) { currentNodeSet = nodeSets.get(node); break; } } } I'll be fixing this up shortly after my current project, which will make it easier for people to apply it to their scripts. Sorry for the inconvienence (wrote these systems from my phone )
  23. I make a thread asking questions which contain very little harassment, it gets deleted and I get 2 warning points. This guy makes a fool out of another guy, and mods like his post. So confused..
  24. Selling any kind of educational services is against the rules /:
  25. So are the values returned both invalid values? That's what you mean by "not providing info to the script"?Run this through your IDE's debugger. I'd give your JCheckBox an ActionListener (which triggers when the item is changed). Put a breakpoint within it, make sure that when you change combobox item, the thread suspends (allowing you to see what happened up to that point). Open up the Variables view and make sure they are the values you want. I'm not at a computer, so not much I can do right now. What I CAN do is suggest: 1. Post your Swing code to the EDT 2. Don't use busy waiting 3. Check out my GUI Settungs guide (http://osbot.org/forum/topic/75074-creating-a-settings-ui-specify-settings-when-script-starts/) 4. DEBUG
×
×
  • Create New...