[XP] RPG Maker XP Online System (RMX-OS)

Started by Blizzard, June 20, 2009, 11:52:23 am

Previous topic - Next topic

edwardthefma

it is hear i fixd the mysql.so error in linux and now you can run rmx-os inside a Linux shell

http://forum.chaos-project.com/index.php/topic,5055.0.html
i am the lead dev for the shellium mmorpg project
http://wiki.shellium.org/w/Mmorpg
shellium.org :) free linux shells pm me and i will gladly
help you get 1

Ryex

hey blizz the name of the whisperer dose not appear in front of received whisper text, it just appears as yellow text and you have no clue who it cam from.
I no longer keep up with posts in the forum very well. If you have a question or comment, about my work, or in general I welcome PM's. if you make a post in one of my threads and I don't reply with in a day or two feel free to PM me and point it out to me.<br /><br />DropBox, the best free file syncing service there is.<br />

Blizzard

Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

Jackolas

December 06, 2009, 10:08:58 am #263 Last Edit: December 06, 2009, 10:12:42 am by Jackolas
k. tried a lot myself. got a lot to work myself. even in the saving stuff..
but ran into a problem :S
I'm not someone to ask for help with every problem because I want to fix everything myself, but I'm stuck
under Save_Data in the manual says :
QuoteIt requires some basic scripting knowledge to set up this configuration! If you are unsure, ask a scripter.


I have a quest system in my game that works great when it was single player (could save an load quest progress.)
Now I can't get it to work any more.

to get it to work in the single player game I added to Scene_Save
    Marshal.dump($game_temp.qupdate, file)
   Marshal.dump($game_temp.qupdate2, file)

in  Game_Temp I added under "class Game_Temp"
  attr_accessor :qupdate
 attr_accessor :qupdate2

and under "def initialize"
    @qupdate = []
   @qupdate2 = []
   for i in 0...200000
     @qupdate[i] = false
     @qupdate2[i] = false
   end

to start a quest i add a script in an event with:
$game_temp.qupdate[1][0] = true

(this will start quest 1 with 0 objective completed)

if more info is needed say so.
Reason for not uploading whole scrip: don't want you guys go to the trouble to read trough 500+ lines of code
if script is really needed i will post it

Blizzard

Add this:

SAVE_DATA[Game_Temp] = ['@qupdate', '@qupdate2']


And add '$game_temp' to SAVE_CONTAINERS.

Also, I recommend that you don't put that stuff in Game_Temp. Better put it in Game_System. Then you need to add '@qupdate' and '@qupdate2' to SAVE_DATA[Game_System] instead of what I just said.
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

Jackolas

December 06, 2009, 12:48:45 pm #265 Last Edit: December 06, 2009, 01:29:43 pm by Jackolas
thanks, i go right to it

edit:
change to system, works like a dream.
added it to SAVE_DATA[Game_System]

got error:

Quote
Script 'RMX-OS Data' line 2600: RuntimeError occurred
Error! Saving for class Array undefined!


think there need to be added a     CREATION_DATA[Game_System] = ????

Blizzard

Right. That's an issue I have fixed already, but it's not in a released version yet. It happens if you have arrays / hashes in arrays / hashes. Put this under RMX-OS for now and it should work:

Spoiler: ShowHide
#==============================================================================
# Object
#------------------------------------------------------------------------------
# Enhanced with methods for self-encoding of contained data and methods for
# decoding of saved game data that was received from the server.
#==============================================================================

class Object
 
  #----------------------------------------------------------------------------
  # Checks whether this object is actually a literal. (Literals are here
  # defined as strings, numbers, ranges, true, false and nil.)
  # Returns: True or false.
  #----------------------------------------------------------------------------
  def literal?
    return (self.is_a?(String) || self.is_a?(Numeric) || self.is_a?(Range) ||
        self.is_a?(TrueClass) || self.is_a?(FalseClass) || self.is_a?(NilClass))
  end
  #----------------------------------------------------------------------------
  # Serializes the object and all contained objects for the RMX-OS SQL
  # database.
  #  prefix - semantical prefix for the serializations
  # Returns: Array of serialization strings.
  #----------------------------------------------------------------------------
  def rmxos_serialize(prefix = nil)
    # add prefix extension if this isn't a top level class
    (prefix == nil ? prefix = 'SAV' : prefix += '/')
    # add class name
    prefix += self.class.name
    # prepare result and data arrays
    serializations, data = [], []
    # for each variable that this class should save
    RMXOS::Options::SAVE_DATA[self.class].each {|variable|
        # get value of variable
        value = self.instance_variable_get(variable)
        # if value is of a class that should be saved as well
        if RMXOS::Options::SAVE_DATA[value.class] != nil ||
            value.is_a?(Array) || value.is_a?(Hash)
          # get serializations from this value with this class as prefix
          serializations += value.rmxos_serialize("#{prefix}/#{variable}")
          data.push(value.class)
        # if value is literal
        elsif value.literal?
          data.push(value)
        else
          # can't save this value
          raise RMXOS::Error.get_save_error(value)
        end}
    # if there is any data
    if data.size > 0
      # inspect and compress
      data = data.inspect.gsub(', ') {','}
      # add data array query
      serializations.unshift("#{prefix}\t#{data}")
    end
    return serializations
  end
  #----------------------------------------------------------------------------
  # Serializes array and hashes for the RMX-OS SQL database.
  #  prefix       - semantical prefix for the serializations
  #  indices      - array of indices (array) or keys (hash)
  #  all_literals - whether all elements are literals or not
  # Returns: Array serialization strings.
  #----------------------------------------------------------------------------
  def rmxos_serialize_enum(prefix, indices, all_literals)
    # prepare result
    serializations = []
    # if all array elements are literals
    if all_literals
      # get as string
      data = self.inspect
    else
      # create new instance of this class
      data = self.class.new
      # for each index in enumerable
      indices.each {|i|
          # if element is literal
          if self[i].literal?
            # add it to the result
            data[i] = self[i]
          # if element is of a class that should be saved as well
          elsif RMXOS::Options::SAVE_DATA[self[i].class] != nil ||
              self[i].is_a?(Array) || self[i].is_a?(Hash)
            # get serializations from this element with this class as prefix
            serializations += self[i].rmxos_serialize("#{prefix}[#{i.inspect}]")
            # add elements's class to data array
            data[i] = self[i].class
          else
            # can't save this value
            raise RMXOS::Error.get_save_error(self[i])
          end}
      # inspect and compress
      data = data.inspect
    end
    # add a little bit of compression :)
    data.gsub!(', ') {','}
    # add data array query
    serializations.push("#{prefix}\t#{data}")
    return serializations
  end
  #----------------------------------------------------------------------------
  # Deserializes data retrieved from the server into this object.
  #  name - the key for the hash data retrieved from the server
  #----------------------------------------------------------------------------
  def rmxos_deserialize(name)
    # evaluate the data for this class which turns into an array
    data = eval($network.load_data[name])
    # iterate through all indices of variables that are to be saved
    RMXOS::Options::SAVE_DATA[self.class].each_index {|i|
        # get variable name
        variable = RMXOS::Options::SAVE_DATA[self.class][i]
        # if this variable's loaded value is a class
        if data[i].is_a?(Class)
          # access key for loaded data
          key = "#{name}/#{variable}"
          # if it's an array
          if data[i] == Array
            # evaluate and get the loaded array
            data[i] = eval($network.load_data[key])
            # load all classes contained in this array
            rmxos_deserialize_enum(name, variable, data[i],
                (0...data[i].size).to_a)
          elsif data[i] == Hash
            # evaluate and get the loaded hash
            data[i] = eval($network.load_data[key])
            # load all classes contained in this hash
            rmxos_deserialize_enum(name, variable, data[i], data[i].keys)
          else
            # load this class
            data[i] = rmxos_deserialize_object(key, data[i])
          end
        end
        # set the variable to this value
        self.instance_variable_set(variable, data[i])}
  end
  #----------------------------------------------------------------------------
  # Deserializes data retrieved from an array or a hash.
  #  name     - the key for the hash data retrieved from the server
  #  variable - name of the variable containing the array
  #  data     - actual array or hash
  #  indices  - array of indices (array) or keys (hash)
  #----------------------------------------------------------------------------
  def rmxos_deserialize_enum(name, variable, data, indices)
    # iterate through all indices
    indices.each {|i|
        # if data is a class
        if data[i].is_a?(Class)
          # access key for loaded data
          key = "#{name}/#{variable}[#{i.inspect}]"
          # if it's an array
          if data[i] == Array
            # evaluate and get the loaded array
            data[i] = eval($network.load_data[key])
            # load all classes contained in this array
            rmxos_deserialize_enum(name, "#{variable}[#{i.inspect}]", data[i],
                (0...data[i].size).to_a)
          elsif data[i] == Hash
            # evaluate and get the loaded hash
            data[i] = eval($network.load_data[key])
            # load all classes contained in this hash
            rmxos_deserialize_enum(name, "#{variable}[#{i.inspect}]", data[i],
                data[i].keys)
          else
            # load this class
            data[i] = rmxos_deserialize_object(key, data[i])
          end
        end}
  end
  #----------------------------------------------------------------------------
  # Deserializes data retrieved from the server into this object.
  #  prefix - semantical prefix for loaded data access
  #  classe - class that needs to be instantiated
  # Returns: New instance of a class after loading.
  #----------------------------------------------------------------------------
  def rmxos_deserialize_object(prefix, classe)
    # if classe requires additional creation arguments
    if RMXOS::Options::CREATION_DATA.has_key?(classe)
      # get the arguments
      args = RMXOS::Options::CREATION_DATA[classe]
      # create an instance with those arguments
      new = eval("#{classe.name}.new(#{args})")
    else
      # simply instantiate the class
      new = classe.new
    end
    # load data for this class
    new.rmxos_deserialize("#{prefix}/#{classe.name}")
    return new
  end
 
end

#==============================================================================
# Array
#------------------------------------------------------------------------------
# Arrays need to be encoded and decoded differently than other obejcts.
#==============================================================================

class Array
 
  #----------------------------------------------------------------------------
  # Serializes the object and all contained objects for the RMX-OS SQL
  # database.
  #  prefix - semantical prefix for the serializations
  # Returns: Array of serialization strings.
  #----------------------------------------------------------------------------
  def rmxos_serialize(prefix)
    # all indices
    indices = (0...self.size).to_a
    # are all elements literals
    all_literals = !self.any? {|val| !val.literal?}
    # return serializations from this array
    return self.rmxos_serialize_enum(prefix, indices, all_literals)
  end

end

#==============================================================================
# Hash
#------------------------------------------------------------------------------
# Hashes need to be encoded and decoded differently than other obejcts.
#==============================================================================

class Hash
 
  #----------------------------------------------------------------------------
  # Serializes the object and all contained objects for the RMX-OS SQL
  # database.
  #  prefix - semantical prefix for the serializations
  # Returns: Array of serialization strings.
  #----------------------------------------------------------------------------
  def rmxos_serialize(prefix)
    # all keys
    indices = self.keys
    # are all elements literals
    all_literals = !self.any? {|key, val| !val.literal?}
    # return serializations from this hash
    return self.rmxos_serialize_enum(prefix, indices, all_literals)
  end 
 
end

module RMXOS
 
  class Network
   
    def send_save_data(classes = RMXOS::Options::SAVE_DATA.keys)
      # repare data for saving
      save_data = {}
      classes.each {|classe|
          save_data[classe] = RMXOS::Options::SAVE_DATA[classe]}
      serializations = []
      # for each save container
      self.get_save_containers.each {|container|
          # if the container's class is on this saving list
          if save_data[container.class] != nil
            # recursively get save serializations
            serializations += container.rmxos_serialize
          end}
      # find all literals
      literals = RMXOS::Options::SAVE_DATA.keys.find_all {|key|
          !key.is_a?(Class)}
      # create serializations for literal saving data
      literals.each {|key| serializations.push("SAV#{key}\t#{eval(key)}")}
      # send all save serializations
      serializations.each {|query| self.send(query)}
    end
   
  end
 
end
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

Jackolas

got it working. till a point
dunno if its a problem in RMX-OS or my quest script

it works fine with log-in (new account ofc) and log-off.
but when I log in again with the same account error pops up

Script 'RMX-OS Data' line 2619: Type Error occurred
Cannot Convert nil into String

sorry to be a pain :S

Blizzard

Fixed as well.

Spoiler: ShowHide
module RMXOS
 
  class Network
 
    def listen
      @messages.clear
      # stop if socket is not ready
      return if !self.connected? || !@socket.ready?
      # get 0xFFFF bytes from  received message
      buffer = @socket.recv(0xFFFF)
      # delete null values from buffer
      buffer.gsub!("\000", '')
      # split messages by \n without suppressing trailing empty strings
      buffer = buffer.split("\n", -1)
      # if chunk from previous incomplete message exists
      if @previous_chunk != nil
        # complete chunk with first new message
        buffer[0] = @previous_chunk + buffer[0]
        # delete chunk buffer
        @previous_chunk = nil
      end
      # remove last message in buffer
      last_chunk = buffer.pop
      # incomplete message if it exists (meaning last message has no \n)
      @previous_chunk = last_chunk if last_chunk != ''
      # check each message in the buffer
      buffer.each {|message|
          next if self.check_game(message)
          next if self.check_communication(message)
          next if self.check_connection(message)
          next if self.check_loading(message)}
    end
   
  end
 
end
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

Jackolas

guess just put it under the rest of the script

had a longer loading
still crashed. same error

Blizzard

Eh, then I don't know. You'll have to wait until I release v1.1. :/
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

Jackolas

np than. will work around it for now :P
thanks for looking into it anyway. :bow:

Ryex

December 06, 2009, 08:34:16 pm #272 Last Edit: December 07, 2009, 12:40:37 am by Ryexander
ok so I'm building a world chat channel addon for PNO I just want to know is the prefix CHW or CAW in use? (and yes I'm aware that mods can use the /global command, this is fo of a use /world to turn world chat off and on, and while your in world chat all your messages are sent to everyone)

EDIT: wow Blizz you weren't thinking of a multichannel system when you designed the chat were you. I ended up giving up on making the world and local chat logs combine correctly and just made it a completely different log.
I no longer keep up with posts in the forum very well. If you have a question or comment, about my work, or in general I welcome PM's. if you make a post in one of my threads and I don't reply with in a day or two feel free to PM me and point it out to me.<br /><br />DropBox, the best free file syncing service there is.<br />

G_G

December 07, 2009, 12:43:29 am #273 Last Edit: December 07, 2009, 12:59:21 am by game_guy
can this run on ruby on rails?

EDIT:
Where go we access all the PM's a player recieves? A friend was bugging me saying he didn't like viewing pm's through chatbox so he asked me to make a script that showed him them.

So I plan on doing that but I need to know how to access PM's.

Blizzard

December 07, 2009, 05:27:18 am #274 Last Edit: December 07, 2009, 05:31:26 am by Blizzard
@Ryex: I did not implement world chat on purpose. Spammers, advertisers, idiots and everybody else falling into that kind of category shouldn't be allowed to talk to everybody whenever they feel like it. There will always be people like that and if they have the means to be completely annoying idiots by annoying everybody else on the server, they will use that opportunity. Imagine 100 people on a server and just 2 pairs of 2 people on two different maps who talk to each other, 2 more annoying idiots who are looking for a pokemon to trade and let the entire server know and 2 more noobs who don't know how to play and keep asking questions. The chatbox will be flooded just like that and a normal conversation with somebody will become impossible.

@G_G: Actually it's in the manual. *points to chapter 4.3.* The PMs are received with the PMA server message. RMXOS::Network#decode_pm_data turns the received string into a proper chat message displaying all the info about the PM.
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

Ryex

@Blizz well Jc and most every one else wanted it and in that case my method of implementing it is better. you don't have to see the world chat if you don't want to.
I no longer keep up with posts in the forum very well. If you have a question or comment, about my work, or in general I welcome PM's. if you make a post in one of my threads and I don't reply with in a day or two feel free to PM me and point it out to me.<br /><br />DropBox, the best free file syncing service there is.<br />

Blizzard

Alright, but I have warned you. :P
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

Ryex

December 07, 2009, 02:23:23 pm #277 Last Edit: December 07, 2009, 02:43:22 pm by Ryexander
yes, yes you did. and yours IS the reason most MMO's have the option to turn the global and trade chat channels off. and even the local channel. so that you can view only the sever messages and personal stuff like pm's or the channel you want to. eventually that is what I'm going to expand it to. a multichannel system where a user receives local messages and messages from channels that they subscribe to. ie the user enters /world into the chat box and the server receives a messages to send world messages to them. and then entering /world again tells it to stop. the same could be done with any extra channel.
It would make a nice extension in that form I think


EDIT:
also in the latest version of PNO I'm having the loading problems again. the type error can't convert nil to string error. I looked up the two lines that it gives, the lines are in the methods rmxos_deserialize and  rmxos_deserialize_enum. the line in both cases is
data = eval($network.load_data[key])
if it helps I was trying to proxy the game client so the network connection never went over 10kb/s and jumped up and down a lot. I have a feeling that this is why
I no longer keep up with posts in the forum very well. If you have a question or comment, about my work, or in general I welcome PM's. if you make a post in one of my threads and I don't reply with in a day or two feel free to PM me and point it out to me.<br /><br />DropBox, the best free file syncing service there is.<br />

Blizzard

December 07, 2009, 05:23:16 pm #278 Last Edit: December 07, 2009, 05:25:27 pm by Blizzard
Alright, then it's ok, channels are fine. I actually hoped that somebody would make plugins to split the different chat message categories. :=

I'm not sure, but the edited client is supposed to receive server message chunks and simply put them together if they aren't complete. Find RMXOS::Network#listen and dump all received messages (before the \000 are all deleted) into a file and send me that file.
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

Lost King

Alright, so, I've spent close to around the last 4 hours tackling the installation of the server alone, mind you I've been having internet connection problems every other minute and everythings been pissing me off like no other. But anyway.

I've finally gotten MySQL to download and got all the way up to the execute window of setting up the instance and it gets to Start Server, the first time I did this it said it couldn't Start, so I closed out, uninstalled, reinstalled, and now it's frozen at that screen twice and I closed out of it after waiting 5 minutes.

Can someone PLEASE help me? Lead me to another alternative? One that isn't a source code and won't take me 4 hours to install. I've got Windows Vista and every new program I come by turns into an adventure regardless of how easy the set up should be. I'm sure getting the actual game to work on the server, if I ever get that working, will take a good 5 hours or so.
*Scribble Scribble* Oh right, not that sort of signature.