Sythe.Org Forums     Register     FAQ     Members List     Calendar     Mark Forums Read    
 
Sythe.Org Forums  
   Runescape Gold

Sythe.org — A Virtual Goods Trading Hub

Make real cash! buying and selling in-game items.

We have a no-scam policy.

You can make thousands playing your favourite games here at Sythe.org.

Just sign up an account and follow the rules!


Take me to

Runescape Markets

Other Game Markets

Support Center

Register an Account

Close
RuneScape Loader for VB2010
Reply
 
LinkBack Thread Tools Display Modes
  #1  
Old 04-22-2011, 01:06 AM
Active Member
Visual Basic Programmers
 
Join Date: Dec 2005
Location: Alberta Canada
Posts: 235
Thumbs up RuneScape Loader for VB2010

Due to some issues with an older RuneScape loader, I decided to rebuild it.

It supports hiding or showing the ads, taking snapshots, multiple game languages and loading RuneScape classic. Also if the X button at the login screen is pressed, it will automatically unload the game.

To use it, add the code below into a new code file, build your projects, add it to your form/usercontrol, the call the LoadGame function.

Code:
Imports System.Runtime.InteropServices

''' <summary>
''' A control for loading RuneScape.
''' </summary> 
<System.Windows.Forms.Docking(DockingBehavior.AutoDock)>
Public Class RuneScapeLoader
    Inherits Control

    Private Const classicUrl As String = "http://www.runescape.com/classicapplet/classicgame.ws?f={0}"
    Private Const gameUrl As String = "http://www.runescape.com{0}/game.ws"

    Public Event GameLoaded As EventHandler
    Public Event GameUnloaded As EventHandler
    Public Event GameLoading As EventHandler

    Private WithEvents Loader As RuneScapeLoaderBrowser
    Private _gameHandle As IntPtr
    Private _hideAds As Boolean = True

    Private Sub Loader_Disposed(sender As Object, e As System.EventArgs) Handles Loader.Disposed
        Me.Loader = Nothing
        RaiseEvent GameUnloaded(Me, EventArgs.Empty)
    End Sub

    Private Sub SetLoaded(gameHandle As IntPtr?)
        Dim gh = If(gameHandle, IntPtr.Zero)
        Me._gameHandle = gh
        If gameHandle.HasValue Then
            RaiseEvent GameLoaded(Me, EventArgs.Empty)
        End If
    End Sub 

    ''' <summary>
    ''' Gets if the RuneScape is currently loaded.
    ''' </summary> 
    <System.ComponentModel.Browsable(False)>
    Public ReadOnly Property IsGameLoaded() As Boolean
        Get
            Return _gameHandle <> IntPtr.Zero
        End Get
    End Property

    ''' <summary>
    ''' Gets if the RuneScape is currently loading.
    ''' </summary> 
    <System.ComponentModel.Browsable(False)>
    Public ReadOnly Property IsGameLoading() As Boolean
        Get
            Return Loader IsNot Nothing AndAlso _gameHandle = IntPtr.Zero
        End Get
    End Property

    ''' <summary>
    ''' Gets the current handle for RuneScape if it is loaded. Otherwise returns nothing. 
    ''' </summary> 
    <System.ComponentModel.Browsable(False)>
    Public ReadOnly Property GameHandle As IntPtr?
        Get
            Return If(_gameHandle = IntPtr.Zero, Nothing, _gameHandle)
        End Get
    End Property

    ''' <summary>
    ''' Gets or sets if the the game loader should hide everything but the game. Set to null, it will only hide the bar at the top for members.
    ''' </summary> 
    Public Property HideAds() As Boolean
        Get
            Return _hideAds
        End Get
        Set(ByVal value As Boolean)
            _hideAds = value
            If IsGameLoaded Then Loader.SetGameBounds(Loader.Url)
        End Set
    End Property

    Private Sub InitLoader()
        If Loader IsNot Nothing Then Throw New InvalidOperationException("RuneScape must be unloaded before it can be reloaded.")
        Me.Loader = New RuneScapeLoaderBrowser(Me)
        Me.Loader.Size = New Size(1000, 1000)
        Me.Controls.Add(Loader)
    End Sub

    ''' <summary>
    ''' Loads RuneScape using the specified language. Defaults to English.
    ''' </summary>
    Public Sub LoadGame(Optional language As GameLanguage = GameLanguage.English)
        InitLoader()
        Loader.Navigate(String.Format(gameUrl, If(language = GameLanguage.English, "", "/l=" + CInt(language))))
        RaiseEvent GameLoading(Me, EventArgs.Empty)
    End Sub

    ''' <summary>
    ''' Loads RuneScape Classic using the specified world. Defaults to the best world.
    ''' </summary> 
    Public Sub LoadClassic(Optional world As Integer? = Nothing)
        InitLoader()
        Loader.Navigate(String.Format(classicUrl, If(world, "best")))
        RaiseEvent GameLoading(Me, EventArgs.Empty)
    End Sub

    ''' <summary>
    ''' Unloads RuneScape.
    ''' </summary> 
    Public Sub UnloadGame()
        If Loader Is Nothing Then Throw New InvalidOperationException("RuneScape must be loaded before it can be unloaded.")
        Loader.Navigate("about:dispose")
    End Sub

    ''' <summary>
    ''' Takes a snapshot of RuneScape and returns an image. If the game is not loaded or there was another problem it will return nothing.
    ''' </summary> 
    Public Function TakeSnapshot() As Image
        If Not IsGameLoaded Then Return Nothing
        Dim lr = New RuneScapeLoaderBrowser.LRTBRect
        RuneScapeLoaderBrowser.GetWindowRect(_gameHandle, lr)
        Dim r = lr.ToRectangle()
        If r.Width = 0 OrElse r.Height = 0 Then Return Nothing
        Dim bmp = New Bitmap(r.Width, r.Height, Imaging.PixelFormat.Format24bppRgb)
        Using g = Graphics.FromImage(bmp)
            g.CopyFromScreen(r.Location, Point.Empty, r.Size)
        End Using
        Return bmp
    End Function

    ''' <summary>
    ''' The languages RuneScape can use
    ''' </summary>
    ''' <remarks></remarks>
    Public Enum GameLanguage
        English = 0
        German = 1
        French = 2
        Portuguese = 3
    End Enum

    Private NotInheritable Class RuneScapeLoaderBrowser
        Inherits WebBrowser

        Public Sub New(host As RuneScapeLoader)
            Me.Host = host
            Me.ScriptErrorsSuppressed = True
            Me.Visible = False
        End Sub

        Public ReadOnly Host As RuneScapeLoader

        Private Shared m As System.Text.RegularExpressions.Regex =
            New System.Text.RegularExpressions.Regex("/l=.+/a=.+/p=.+")

#Region "Game Handle"

        Public Delegate Function EnumWindowCallback(handle As IntPtr, listHandle As IntPtr) As Boolean
        Public Declare Auto Function EnumChildWindows Lib "user32" (window As IntPtr, callback As EnumWindowCallback, listHandle As IntPtr) As Boolean
        Public Declare Auto Function GetWindowRect Lib "user32" (window As IntPtr, ByRef rect As LRTBRect) As Boolean

        Public Structure LRTBRect
            Public Left, Top, Right, Bottom As Integer
            Public Function ToRectangle() As Rectangle
                Return Rectangle.FromLTRB(Left, Top, Right, Bottom)
            End Function
        End Structure

        ''' <summary>
        ''' Gets the handle and bounds of the loaded RuneScape client.
        ''' </summary>
        Friend Function GetRuneScapeHandle() As Tuple(Of IntPtr, Rectangle)
            Dim l As New List(Of Tuple(Of IntPtr, Rectangle))()
            Dim gc = GCHandle.Alloc(l)
            Try
                EnumChildWindows(Me.Handle, AddressOf EnumWindowCB, GCHandle.ToIntPtr(gc))
            Finally
                If (gc.IsAllocated) Then gc.Free()
            End Try
            Return Aggregate x In l Into FirstOrDefault(x.Item2.Height >= 503 AndAlso x.Item2.Height < Me.Height)
        End Function

        ''' <summary>
        ''' Adds the window handle and bounds of the window to the list.
        ''' </summary> 
        Private Shared Function EnumWindowCB(handle As IntPtr, listHandle As IntPtr) As Boolean
            Dim gc = GCHandle.FromIntPtr(listHandle)
            Dim l = TryCast(gc.Target, List(Of Tuple(Of IntPtr, Rectangle)))
            If l Is Nothing Then Throw New InvalidCastException("GCHandle target could not be cast as List(Of Tuple(Of IntPtr, Rectangle)).")
            Dim r = New LRTBRect
            GetWindowRect(handle, r)
            l.Add(Tuple.Create(handle, r.ToRectangle()))
            Return True
        End Function

#End Region

        Protected Overrides Sub OnDocumentCompleted(e As System.Windows.Forms.WebBrowserDocumentCompletedEventArgs) 
            Dim Url = e.Url
            ' If the desired url is about:dispose, it will try to dispose of the browser.
            If url.ToString().ToLower() = "about:dispose" Then
                Me.BeginInvoke(New Action(AddressOf Dispose))
                Return
            End If
            SetGameBounds(url)
        End Sub
         
        Public Sub SetGameBounds(url As Uri)
            ' Checks if the url is valid.
            Dim isRuneScape = url.LocalPath.ToLower().EndsWith("/game.ws") AndAlso url.Host.ToLower() = "www.runescape.com"
            Dim isRSClassic = url.Host.ToLower().StartsWith("classic") AndAlso url.Host.ToLower().EndsWith(".runescape.com")
            If isRuneScape = isRSClassic Then Return
            Dim target = Me.GetRuneScapeHandle()
            If target Is Nothing OrElse target.Item1 = IntPtr.Zero Then Return
            ' Gets the required bounds of the web browser to hide everything but the game.
            Dim targetRect = target.Item2
            targetRect.Location -= Me.PointToScreen(Point.Empty)
            Me.Anchor = 15 
            Me.Bounds = If(Host.HideAds, New Rectangle(-targetRect.X, -targetRect.Y, Parent.Width + (Me.Width - targetRect.Width), Parent.Height + (Me.Height - targetRect.Height)), Parent.ClientRectangle)
            Me.Show()
            Me.Host.SetLoaded(target.Item1)
        End Sub

        Protected Overrides Sub OnNavigating(e As System.Windows.Forms.WebBrowserNavigatingEventArgs)
            ' Makes sure the browser is disposed if going to the homepage.
            If m.IsMatch(e.Url.AbsolutePath.ToLower()) Then
                e.Cancel = True
                Me.Navigate("about:dispose")
            End If
        End Sub

        Protected Overrides Sub Dispose(disposing As Boolean)
            Host.SetLoaded(Nothing)
            MyBase.Dispose(disposing)
        End Sub

    End Class

End Class
Edit: Added an IsGameLoading property and GameLoading event to notify if the game is still loading, instead of some unknown state.

Last edited by Flaming Idiots : 04-28-2011 at 07:05 PM.
Reply With Quote
  #2  
Old 04-28-2011, 02:37 PM
Covey's Avatar
Creator of EliteSwitch
Ex-Moderator Visual Basic Programmers
 
Join Date: Sep 2005
Location: Fuckin' BAM!
Posts: 4,464
Default Re: RuneScape Loader for VB2010

Hey Flaming, nice work
Just one question about a problem i'm having.
When i load a classic world and then load a normal world (or vice-a-versa) if i don't wait until the game has finished loading it throws an errors saying "the game must be unloaded for it to be loaded".
Even though i have the following before my "Loadgame" call:
Code:
If rsMain.Visible = True Then 'this identifies a world has already been loaded
            rsMain.UnloadGame()
            Application.DoEvents()
        End If
__________________
EliteSwitch v4 Source Code - http://sythe.org/showthread.php?t=1214654
Reply With Quote
  #3  
Old 04-28-2011, 07:20 PM
Active Member
Visual Basic Programmers
 
Join Date: Dec 2005
Location: Alberta Canada
Posts: 235
Default Re: RuneScape Loader for VB2010

If you unload the game, you must wait until the GameUnloaded event is raised before you can load another world (it's to make sure that Java doesn't explode). The easy way to fix this is just to disable the buttons while the game is loading.

If that's not an option, you can tell it to load the game after it's been unloaded like this:

Code:
Private unloadAction As Action

Private Sub RuneScapeLoader_GameUnloaded(sender As System.Object, e As System.EventArgs) Handles RuneScapeLoader.GameUnloaded
    If unloadAction IsNot Nothing AndAlso Not (RuneScapeLoader.Disposing OrElse RuneScapeLoader.IsDisposed) Then
        RuneScapeLoader.BeginInvoke(unloadAction)
        unloadAction = Nothing
    End If
End Sub

Private Sub LoadGameButton_Click(sender As System.Object, e As System.EventArgs) Handles LoadGameButton.Click
    With Me.RuneScapeLoader
        If Not (.IsGameLoading OrElse .IsGameLoaded) Then
            .LoadGame()
        Else
            unloadAction = Sub() .LoadGame()
            .UnloadGame()
        End If
    End With
End Sub

Private Sub LoadClassicButton_Click(sender As Object, e As System.EventArgs) Handles LoadClassicButton.Click
    With Me.RuneScapeLoader
        If Not (.IsGameLoading OrElse .IsGameLoaded) Then
            .LoadClassic()
        Else
            unloadAction = Sub() .LoadClassic()
            .UnloadGame()
        End If
    End With
End Sub

Private Sub UnloadGameButton_Click(sender As Object, e As System.EventArgs) Handles UnloadGameButton.Click
    With Me.RuneScapeLoader
        unloadAction = Nothing
        If .IsGameLoaded OrElse .IsGameLoading Then .UnloadGame()
    End With
End Sub
Reply With Quote
  #4  
Old 04-29-2011, 02:07 AM
Covey's Avatar
Creator of EliteSwitch
Ex-Moderator Visual Basic Programmers
 
Join Date: Sep 2005
Location: Fuckin' BAM!
Posts: 4,464
Default Re: RuneScape Loader for VB2010

Thanks FI, i'll go with the simplicity or disabling the buttons
__________________
EliteSwitch v4 Source Code - http://sythe.org/showthread.php?t=1214654
Reply With Quote
  #5  
Old 04-29-2011, 01:41 PM
Covey's Avatar
Creator of EliteSwitch
Ex-Moderator Visual Basic Programmers
 
Join Date: Sep 2005
Location: Fuckin' BAM!
Posts: 4,464
Default Re: RuneScape Loader for VB2010

Found a fix for it, replace the InitLoader() sub with this:
Code:
    Private Sub InitLoader()
        If Loader IsNot Nothing Then
            UnloadGame()
            Do Until Loader Is Nothing
                Application.DoEvents()

            Loop
        End If
        If Loader IsNot Nothing Then Throw New InvalidOperationException("RuneScape must be unloaded before it can be reloaded.")
        Me.Loader = New RuneScapeLoaderBrowser(Me)
        Me.Loader.Size = New Size(1000, 1000)
        Me.Controls.Add(Loader)
    End Sub
__________________
EliteSwitch v4 Source Code - http://sythe.org/showthread.php?t=1214654
Reply With Quote
Reply



Cheap RS Gold Store  Runescape Gold

Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are Off
Refbacks are Off

All times are GMT +1. The time now is 02:24 AM.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2013, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.6.1