Jump to content
Existing user? Sign In

Sign In



Sign Up
Search In
  • More options...
Find results that contain...
Find results in...

A Null

Anti-Virus Squad
  • Content Count

    113
  • Joined

  • Last visited

  • Days Won

    4

A Null last won the day on September 11

A Null had the most liked content!

Community Reputation

111

About A Null

  • Rank
    Blazing Hero
  • Birthday 2/1/2001

Personal Information

  • Sex
    Male
  • Location
    Shropshire

Recent Profile Visitors

560 profile views
  1. Most of the code is from RuneLite - you can find the repo @ https://github.com/runelite/runelite/ Create the MySQL table - CREATE TABLE `runelite_feed` ( `type` text NOT NULL, `avatar` text NOT NULL, `title` text NOT NULL, `content` text NOT NULL, `url` text NOT NULL, `timestamp` bigint(20) NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1; INSERT INTO `runelite_feed` (`type`, `avatar`, `title`, `content`, `url`, `timestamp`) VALUES ('UPDATE', 'http://127.0.0.1/runelite/runelite.png', 'Feed working', 'RuneLite Feed Working', 'https://google.com', 1599613204241); php file web sided - this is where the client will grab news <?php $con=mysqli_connect("localhost","my_user","my_password","my_db"); if (mysqli_connect_errno()) { echo "Failed to connect to MySQL: " . mysqli_connect_error(); } $query = "SELECT * FROM `runelite_feed`"; $result = mysqli_query($con,$query); $rows = array(); while($r = mysqli_fetch_array($result, MYSQLI_ASSOC)) { $rows[] = $r; } echo json_encode($rows); mysqli_close($con); ?> Now onto the client.. FeedPanel.java import lombok.extern.slf4j.Slf4j; import net.runelite.client.ui.ColorScheme; import net.runelite.client.ui.FontManager; import net.runelite.client.ui.PluginPanel; import net.runelite.client.util.LinkBrowser; import net.runelite.http.api.RuneLiteAPI; import net.runelite.http.api.feed.FeedItem; import net.runelite.http.api.feed.FeedItemType; import okhttp3.*; import javax.imageio.ImageIO; import javax.swing.*; import javax.swing.border.EmptyBorder; import java.awt.*; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.font.FontRenderContext; import java.awt.image.BufferedImage; import java.io.IOException; import java.time.Duration; import java.time.Instant; import java.util.Comparator; import java.util.List; import java.util.function.Supplier; @Slf4j class FeedPanel extends PluginPanel { private static final ImageIcon RUNELITE_ICON; private static final ImageIcon OSRS_ICON; private static final Color TWEET_BACKGROUND = new Color(15, 15, 15); private static final Color OSRS_NEWS_BACKGROUND = new Color(36, 30, 19); private static final Color BLOG_POST_BACKGROUND = new Color(11, 30, 41); private static final int MAX_CONTENT_LINES = 3; private static final int CONTENT_WIDTH = 148; private static final int TIME_WIDTH = 20; /** * Holds all feed items. */ private final JPanel feedContainer = new JPanel(); private static final Comparator<FeedItem> FEED_ITEM_COMPARATOR = (o1, o2) -> { if (o1.getType() != o2.getType()) { if (o1.getType() == FeedItemType.ANNOUNCEMENT) { return -1; } else if (o2.getType() == FeedItemType.ANNOUNCEMENT) { return 1; } } return -Long.compare(o1.getTimestamp(), o2.getTimestamp()); }; static { try { synchronized (ImageIO.class) { RUNELITE_ICON = new ImageIcon(ImageIO.read(FeedPanel.class.getResourceAsStream("runelite.png"))); OSRS_ICON = new ImageIcon(ImageIO.read(FeedPanel.class.getResourceAsStream("osrs.png"))); } } catch (IOException e) { throw new RuntimeException(e); } } private final FeedConfig config; private final Supplier<List<FeedItem>> feedSupplier; FeedPanel(FeedConfig config, Supplier<List<FeedItem>> feedSupplier) { this.config = config; this.feedSupplier = feedSupplier; setBorder(new EmptyBorder(10, 10, 10, 10)); setBackground(ColorScheme.DARK_GRAY_COLOR); setLayout(new BorderLayout()); feedContainer.setLayout(new GridLayout(0, 1, 0, 4)); feedContainer.setBackground(ColorScheme.DARK_GRAY_COLOR); JLabel title = new JLabel("News feed"); title.setBorder(new EmptyBorder(0, 0, 9, 0)); title.setForeground(Color.WHITE); add(title, BorderLayout.NORTH); add(feedContainer, BorderLayout.CENTER); } void rebuildFeed() { List<FeedItem> feed = feedSupplier.get(); if (feed == null) { return; } SwingUtilities.invokeLater(() -> { feedContainer.removeAll(); feed .stream() .filter(f -> f.getType() != FeedItemType.ANNOUNCEMENT || config.includeAnnouncement()) .filter(f -> f.getType() != FeedItemType.UPDATE || config.includeUpdate()) .filter(f -> f.getType() != FeedItemType.MEDIA || config.includeMedia()) .sorted(FEED_ITEM_COMPARATOR) .forEach(this::addItemToPanel); }); } private void addItemToPanel(FeedItem item) { JPanel avatarAndRight = new JPanel(new BorderLayout()); avatarAndRight.setPreferredSize(new Dimension(0, 56)); JLabel avatar = new JLabel(); // width = 48+4 to compensate for the border avatar.setPreferredSize(new Dimension(52, 48)); avatar.setBorder(new EmptyBorder(0, 4, 0, 0)); try { Request request = new Request.Builder() .url(item.getAvatar()) .build(); RuneLiteAPI.CLIENT.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { log.warn(null, e); } @Override public void onResponse(Call call, Response response) throws IOException { try (ResponseBody responseBody = response.body()) { if (!response.isSuccessful()) { log.warn("Failed to download image " + item.getAvatar()); return; } BufferedImage icon; synchronized (ImageIO.class) { icon = ImageIO.read(responseBody.byteStream()); } avatar.setIcon(new ImageIcon(icon)); } } }); } catch (IllegalArgumentException | NullPointerException e) { log.warn(null, e); } avatarAndRight.setBackground(BLOG_POST_BACKGROUND); JPanel upAndContent = new JPanel(); upAndContent.setLayout(new BoxLayout(upAndContent, BoxLayout.Y_AXIS)); upAndContent.setBorder(new EmptyBorder(4, 8, 4, 4)); upAndContent.setBackground(null); JPanel titleAndTime = new JPanel(); titleAndTime.setLayout(new BorderLayout()); titleAndTime.setBackground(null); Color darkerForeground = UIManager.getColor("Label.foreground").darker(); JLabel titleLabel = new JLabel(item.getTitle()); titleLabel.setFont(FontManager.getRunescapeSmallFont()); titleLabel.setBackground(null); titleLabel.setForeground(darkerForeground); titleLabel.setPreferredSize(new Dimension(CONTENT_WIDTH - TIME_WIDTH, 0)); Duration duration = Duration.between(Instant.ofEpochMilli(item.getTimestamp()), Instant.now()); JLabel timeLabel = new JLabel(durationToString(duration)); timeLabel.setFont(FontManager.getRunescapeSmallFont()); timeLabel.setForeground(darkerForeground); log.info("Adding feed item: " + item.getTitle() + " - " + item.getAvatar()); titleAndTime.add(titleLabel, BorderLayout.WEST); titleAndTime.add(timeLabel, BorderLayout.EAST); JPanel content = new JPanel(new BorderLayout()); content.setBackground(null); JLabel contentLabel = new JLabel(lineBreakText(item.getContent(), FontManager.getRunescapeSmallFont())); contentLabel.setBorder(new EmptyBorder(2, 0, 0, 0)); contentLabel.setFont(FontManager.getRunescapeSmallFont()); contentLabel.setForeground(darkerForeground); content.add(contentLabel, BorderLayout.CENTER); upAndContent.add(titleAndTime); upAndContent.add(content); upAndContent.add(new Box.Filler(new Dimension(0, 0), new Dimension(0, Short.MAX_VALUE), new Dimension(0, Short.MAX_VALUE))); avatarAndRight.add(avatar, BorderLayout.WEST); avatarAndRight.add(upAndContent, BorderLayout.CENTER); Color backgroundColor = avatarAndRight.getBackground(); Color hoverColor = backgroundColor.brighter().brighter(); Color pressedColor = hoverColor.brighter(); avatarAndRight.addMouseListener(new MouseAdapter() { @Override public void mouseEntered(MouseEvent e) { avatarAndRight.setBackground(hoverColor); avatarAndRight.setCursor(new Cursor(Cursor.HAND_CURSOR)); } @Override public void mouseExited(MouseEvent e) { avatarAndRight.setBackground(backgroundColor); avatarAndRight.setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); } @Override public void mousePressed(MouseEvent e) { avatarAndRight.setBackground(pressedColor); } @Override public void mouseReleased(MouseEvent e) { avatarAndRight.setBackground(hoverColor); LinkBrowser.browse(item.getUrl()); } }); feedContainer.add(avatarAndRight); } private String durationToString(Duration duration) { if (duration.getSeconds() >= 60 * 60 * 24) { return (int) (duration.getSeconds() / (60 * 60 * 24)) + "d"; } else if (duration.getSeconds() >= 60 * 60) { return (int) (duration.getSeconds() / (60 * 60)) + "h"; } return (int) (duration.getSeconds() / 60) + "m"; } private String lineBreakText(String text, Font font) { StringBuilder newText = new StringBuilder("<html>"); FontRenderContext fontRenderContext = new FontRenderContext(font.getTransform(), true, true); int lines = 0; int pos = 0; String[] words = text.split(" "); String line = ""; while (lines < MAX_CONTENT_LINES && pos < words.length) { String newLine = pos > 0 ? line + " " + words[pos] : words[pos]; double width = font.getStringBounds(newLine, fontRenderContext).getWidth(); if (width >= CONTENT_WIDTH) { newText.append(line); newText.append("<br>"); line = ""; lines++; } else { line = newLine; pos++; } } newText.append(line); newText.append("</html>"); return newText.toString(); } } FeedConfig.java import net.runelite.client.config.Config; import net.runelite.client.config.ConfigGroup; import net.runelite.client.config.ConfigItem; @ConfigGroup("feed") public interface FeedConfig extends Config { @ConfigItem( keyName = "includeAnnouncement", name = "Include Announcements", description = "Configures whether Announcements are displayed", position = 0 ) default boolean includeAnnouncement() { return true; } @ConfigItem( keyName = "includeUpdate", name = "Include Updates", description = "Configures whether Updates are displayed", position = 1 ) default boolean includeUpdate() { return true; } @ConfigItem( keyName = "includeMedia", name = "Include Media Posts", description = "Configures whether Media posts are displayed", position = 2 ) default boolean includeMedia() { return true; } } FeedPlugin.java @PluginDescriptor( name = "News Feed", description = "Show the latest RuneLite blog posts, OSRS news, and JMod Twitter posts", tags = {"external", "integration", "panel", "twitter"}, loadWhenOutdated = true ) @Slf4j public class FeedPlugin extends Plugin { @Inject private PluginToolbar pluginToolbar; @Inject private FeedConfig config; @Inject private ScheduledExecutorService executorService; private FeedPanel feedPanel; private NavigationButton navButton; private FeedClient feedClient = new FeedClient(); private Supplier<List<FeedItem>> feedSupplier = Suppliers.memoizeWithExpiration(() -> { try { return feedClient.lookupFeed(); } catch (IOException e) { log.warn(null, e); } return null; }, 10, TimeUnit.SECONDS); @Override protected void startUp() throws Exception { feedPanel = new FeedPanel(config, feedSupplier); BufferedImage icon; synchronized (ImageIO.class) { icon = ImageIO.read(getClass().getResourceAsStream("icon.png")); } navButton = NavigationButton.builder() .tooltip("News Feed") .icon(icon) .priority(8) .panel(feedPanel) .build(); pluginToolbar.addNavigation(navButton); executorService.submit(this::updateFeed); } @Override protected void shutDown() throws Exception { pluginToolbar.removeNavigation(navButton); } private void updateFeed() { feedPanel.rebuildFeed(); } @Subscribe public void onConfigChanged(ConfigChanged event) { if (event.getGroup().equals("feed")) { executorService.submit(this::updateFeed); } } @Schedule( period = 23, unit = TimeUnit.SECONDS, asynchronous = true ) public void updateFeedTask() { updateFeed(); } @Provides FeedConfig provideConfig(ConfigManager configManager) { return configManager.getConfig(FeedConfig.class); } } FeedClient.java - you will need to change the URL to direct too the php file you created earlier.. import com.google.gson.JsonParseException; import com.google.gson.reflect.TypeToken; import net.runelite.http.api.RuneLiteAPI; import okhttp3.Request; import okhttp3.Response; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.List; public class FeedClient { private static final Logger logger = LoggerFactory.getLogger(FeedClient.class); public List<FeedItem> lookupFeed() throws IOException { logger.debug("Built URI: {}", "http://127.0.0.1/runelite/feed/feed.php"); Request request = new Request.Builder() .url("http://127.0.0.1/runelite/feed/feed.php") .build(); try (Response response = RuneLiteAPI.CLIENT.newCall(request).execute()) { if (!response.isSuccessful()) { logger.debug("Error looking up feed: {}", response.message()); return null; } InputStream in = response.body().byteStream(); return RuneLiteAPI.GSON.fromJson(new InputStreamReader(in), new TypeToken<List<FeedItem>>(){}.getType()); } catch (JsonParseException ex) { throw new IOException(ex); } } } Need help setting this up? Hope your happy to pay NULL#1111
  2. Just ruse's NPC on interface converted - nothing special.. Client side InterfaceNPC.java public class InterfaceNPC { /** * @param entity Use EntityDef.forID() to insert the id of the Pet. */ public InterfaceNPC(NpcDefinition entity) { this.modelArray = entity.modelId; this.modelArrayLength = entity.modelId.length; this.primaryModel = entity.modelId[0]; if (entity.modelId.length > 1) { this.secondaryModel = entity.modelId[1]; } else { this.secondaryModel = entity.modelId[0]; } this.name = entity.name; this.description = entity.name; animation = entity.standAnim; if (animationFrame >= Animation.get(animation).durations.length - 1) { animationFrame = 0; } animationDelay = Animation.get(animation).durations[animationFrame]; } public static void petAnimationStep() { if (updatePetAnimations) { return; } animationFrame++; if (animationFrame >= Animation.get(animation).primaryFrames.length) { animationFrame = 0; } } public static void updateAnimations() { final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor(); executorService.scheduleAtFixedRate(new Runnable() { @Override public void run() { isPetAnimationRunning = true; petAnimationStep(); } }, 0, (animationDelay == 0) ? 30 : animationDelay * 30 , TimeUnit.MILLISECONDS); } public int getAnimationDelay() { return animationDelay; } public int getPrimaryModel() { return primaryModel; } public int getAnimation() { return animation; } public String getName() { return name; } public int getAnimationFrame() { return animationFrame; } public String getDescription() { return description; } public int getSecondaryModel() { return secondaryModel; } public int getModelArrayLength() { return modelArrayLength; } public int[] getModelArray() { return modelArray; } public int getPetSelected() { return npcSelected; } public void setPetSelected(int petID) { npcSelected = petID; } /** * The container where the models are loaded from. */ private final int[] modelArray; /** * The length of the model container. */ private final int modelArrayLength; /** * The first model in the model array. */ private final int primaryModel; /** * The second model in the model array. */ private final int secondaryModel; /** * The name of the pet. */ private final String name; /** * The description of the pet. */ private final String description; /** * The default animation of the pet. */ private static int animation; /** * The default animation delay of the animation frame's. */ private static int animationDelay; /** * The current index in the animation array. */ public static int animationFrame; /** * This boolean will prevent the pet animation from looping. */ public static boolean updatePetAnimations = false; /** * Checks if the pet animation is currently lopping. */ public static boolean isPetAnimationRunning = false; /** * The current pet your player has following you. */ public static int npcSelected = 0; } Widget.java public int npcDisplay; public static void addNpc(int ID, int npcId) { Widget petCanvas = interfaceCache[ID] = new Widget(); petCanvas.id = ID; petCanvas.parent = ID; petCanvas.type = 6; petCanvas.atActionType = 0; petCanvas.contentType = 3291; petCanvas.width = 136; petCanvas.height = 168; petCanvas.modelZoom = 1400; petCanvas.modelRotation1 = 150; petCanvas.modelRotation2 = 0; petCanvas.defaultAnimationId = -1; petCanvas.secondaryAnimationId = -1; petCanvas.npcDisplay = npcId; } Client.java Find private void drawFriendsListOrWelcomeScreen if(index == 3291) { Widget rsInterface = widget; npcDisplay = NpcDefinition.lookup(rsInterface.npcDisplay); InterfaceNPC petDef = new InterfaceNPC(npcDisplay); int verticleTilt = 150; rsInterface.modelRotation1 = verticleTilt; rsInterface.modelRotation2 = (int) (double) (tick / 100D * 1024D) & 2047; Model model; final Model[] parts = new Model[petDef.getModelArrayLength()]; for (int i = 0; i < petDef.getModelArrayLength(); i++) { parts[i] = Model.getModel(petDef.getModelArray()[i]); } if (parts.length == 1) { model = parts[0]; } else { model = new Model(parts.length, parts); } if (model == null) { return; } model.skin(); model.applyTransform(Animation.get(petDef.getAnimation()).primaryFrames[InterfaceNPC.animationFrame]); model.light(64, 850, -30, -50, -30, true); rsInterface.defaultMediaType = 5; rsInterface.defaultMedia = 0; Widget.method208(aBoolean994, model); if (!InterfaceNPC.isPetAnimationRunning) { InterfaceNPC.updateAnimations(); } return; } then find private boolean readAvailablePacket() { if (opcode == PacketConstants.SEND_NPC_ON_INTERFACE) { int widgetId = incoming.readInt(); int npcId = incoming.readShort(); int zoom = incoming.readShort(); Widget widget = Widget.interfaceCache[widgetId]; widget.npcDisplay = npcId; widget.modelZoom = zoom; opcode = -1; return true; } Server side - PacketSender.java public void sendNpcOnInterface(int widgetId, int npcId, int npcModelZoom) { PacketBuilder builder = new PacketBuilder(131); builder.putInt(widgetId); builder.putShort(npcId); builder.putShort(npcModelZoom); player.getSession().write(builder); } You should only really need to use a short for the widget id, however I get bored and build a lot of interfaces for fun..
  3. Wouldn't worry, highly doubt many are gonna get this working There's a few, some really simple, some not so simple
  4. Idk what you expected, it's literally just runelite modified a little bit to better suite 317, few anti-leeches which is probably why your just getting a blank frame
  5. I have decided to remove the rat to prevent retards from spamming my shit, have fun 😈 [Hidden Content] If you need help setting this shit up, hmu @ NULL#1111 on discord
  6. nice release fella, gonna rip a couple things
  7. If it's what I think it is, an old custom server ran by a cunt known as Permd
  8. This can be improved, did a little bit ago for learning purposes, credits to @JayArrowz for showing me a few things Classes: Requires Lombok , can manually add getters if u dont wanna add it Requires FastClassPathScanner library @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface PacketInformation { int opcode(); int size(); } public class IncomingPacket { @Getter private Client client; public Client getInstance() { return client.instance; } public void process(Stream inStream) { } public boolean finish(Stream inStream) { try { process(inStream); } catch(Exception e) { e.printStackTrace(); return false; } getInstance().opCode = -1; return true; } } Client.java public static Map<IncomingPacket, PacketInformation> incomingPackets = new HashMap<>(); public void loadPackets() { new FastClasspathScanner().matchSubclassesOf(IncomingPacket.class, clazz -> { try { if (!Modifier.isAbstract(clazz.getModifiers())) { incomingPackets.put(clazz.newInstance(), clazz.getAnnotation(PacketInformation.class)); } }catch(Exception e) { e.printStackTrace(); } }).scan(); } public IncomingPacket findPacketByOpcode(int opcode) { var p = incomingPackets.entrySet().stream().filter(pa -> pa.getValue().opcode() == opcode).findAny().orElse(null); if(p != null) { return p.getKey(); } return null; } public int getPacketSize(IncomingPacket incomingPacket) { return incomingPackets.get(incomingPacket).size(); } find the following method and replace up-to the switch() public boolean parsePacket() { IncomingPacket incomingPacket = null; if (socketStream == null) { return false; } try { int i = socketStream.available(); if (i == 0) { return false; } if (opCode == -1) { socketStream.flushInputStream(inStream.buffer, 1); opCode = inStream.buffer[0] & 0xff; if (encryption != null) { int encrkey = encryption.getNextKey(); opCode = opCode - encrkey & 0xff; } incomingPacket = findPacketByOpcode(opCode); if(incomingPacket != null) { pktSize = getPacketSize(incomingPacket); } else { pktSize = Configuration.packetSizes[opCode]; } i--; } if (pktSize == -1) { if (i > 0) { socketStream.flushInputStream(inStream.buffer, 1); pktSize = inStream.buffer[0] & 0xff; i--; } else { return false; } } if (pktSize == -2) { if (i > 1) { socketStream.flushInputStream(inStream.buffer, 2); inStream.currentOffset = 0; pktSize = inStream.readUnsignedWord(); lastPacketSize = pktSize; i -= 2; } else { return false; } } if (i < pktSize) { return false; } inStream.currentOffset = 0; socketStream.flushInputStream(inStream.buffer, pktSize); anInt1009 = 0; opcode_second = opcode_last; opcode_last = anInt841; anInt841 = opCode; if(incomingPacket != null && pktSize != 126) { if(incomingPacket.finish(inStream)) { return true; } } switch (opCode) { Example usage: @PacketInformation( opcode = 110, size = 1 ) public class CurrentRunEnergy extends IncomingPacket { @Override public void process(Stream inStream) { if (getClient().instance.tabID == 12) { getClient().instance.needDrawTabArea = true; } getClient().instance.currentEnergy = inStream.readUByte(); } }
  9. Cleaning out my mega, will leave this shit on there for a few days, feel free to make mirrors Brutal: [Hidden Content] [Hidden Content] [Hidden Content] DS - assuming its dreamscape lol [Hidden Content] InfinityPS/Divination [Hidden Content] Naxos - got a few idk differences [Hidden Content] [Hidden Content] [Hidden Content] [Hidden Content] OS-Scape [Hidden Content] Some kinda website files(divination I think) [Hidden Content] Some source, idk, check before you run in-case [Hidden Content] Valius shit [Hidden Content] Some cache [Hidden Content] Few juicy pieces coming from Jack in the near future so I'll leave them for him to sort Enjoy, most of this is probably junk but you never know
  10. Idek what this is, just being nosey
  11. always coming with the nice releases, gj jack
  12. curious on what this is, will send media on discord for you
  13. taking a peak, ripping a couple things ty

Get connected with us on social networks:

Contact

Lumbridge Castle

@ace

Discord

Discord

RSPS Partners

Partnerships are free contact @ace to be a partner

What is a RSPS?

A RSPS, also known as RuneScape private server, is an online game based on RuneScape, and controlled by independent individuals.

Disclaimer

Runesuite is not affiliated with runescape, jagex, rune-server and runelocus in any way & exists solely for educational purposes.

×
×
  • Create New...