Teil 1
Code:
#--------------------------------------------------------------------------
# * Benötigte Methoden
#--------------------------------------------------------------------------
class Class
  #--------------------------------------------------------------------------
  # * Erzeugt alternative Namen für eine Methode -KD
  #--------------------------------------------------------------------------
  def link(methode, *namen)
    namen.each {|n| define_method(n) {|*a| method(methode).call(*a)}}
  end
  def link_classmethod(methode, *namen)
    $methode = methode
    namen.each {|n| 
      $n = n
      class << self
        methode, n = $methode, $n
        define_method(n) {|*a| self.method(methode).call(*a)} 
      end
    }
    $methode = nil
    $n = nil
  end
end
class Array
  #--------------------------------------------------------------------------
  # * Addiert zwei Arrays ohne doppelte o. leere Elemente hinzuzufügen -KD
  #--------------------------------------------------------------------------
  def add(*args)
    args.each {|e| push(e) unless include?(e) or e.empty?} 
  end
end
class Hash
  #--------------------------------------------------------------------------
  # * Sucht nach einem passenden Key für einen Value/Suchblock -KD
  #--------------------------------------------------------------------------
  def key_for_value(search_value)
    key = nil
    ergebnis = each_pair {|key, value|
      break if if block_given? then
        yield(value, search_value)
      else
        value == search_value
      end
      true
    }
    if ergebnis then false else key end
  end
end
class Symbol
  #--------------------------------------------------------------------------
  # * Macht ein Symbol zu einem Instanzvariablensymbol -KD
  #--------------------------------------------------------------------------
  def to_isym
    return ('@' + self.to_s).to_sym
  end
end

class Fixnum
  #--------------------------------------------------------------------------
  # * Liefert einen String mit einer n-stellen Zahl. -KD
  #--------------------------------------------------------------------------
  def zu_nstelligen_string(n)
    vor = ""
    (n-1).downto(0) {|stelle| vor = vor.concat('0') if self < 10**stelle }
    vor.concat(self.to_s)
  end
end

class Float
  #--------------------------------------------------------------------------
  # * Gibt Datengröße an. -KD
  #--------------------------------------------------------------------------
  EINHEITEN = ["byte", "kb", "mb", "gb"]
  def datasize
    size = self; counter = 0
    while counter < EINHEITEN.size-1 and (a=size / 1024) >= 0.1
      size = a; counter += 1;
    end
    size.to_s + ' ' + EINHEITEN[counter]
  end
end

class File
  #--------------------------------------------------------------------------
  # * Überprüft, ob der Dateiname auf eine Ressourcendatei zeigt -KD
  #--------------------------------------------------------------------------
  def self.ressource?(pfad, *possible_endings)
    pfad =~ /.+\.(.+)/
    !(possible_endings.find {|e| e == $1}).nil?
  end
  #--------------------------------------------------------------------------
  # * Erzeugt einen Ordner - WATANABE, Hirofumi (Ruby Standard Library)
  #--------------------------------------------------------------------------
  def self.makedirs(*dirs)
    verbose = if dirs[-1].is_a? String then false else dirs.pop end
    mode = 0755
    for dir in dirs
      parent = dirname(dir)
      next if parent == dir or directory? dir
      makedirs parent unless directory? parent
      $stderr.print "mkdir ", dir, "\n" if verbose
      if basename(dir) != ""
        begin
          Dir.mkdir dir, mode
        rescue SystemCallError
          raise unless directory? dir
        end
      end
    end
  end
  #--------------------------------------------------------------------------
  # * Sucht nach Dateien - (Ruby Standard Library)
  #--------------------------------------------------------------------------
  def self.find(*paths)
    paths.collect!{|d| d.dup}
    while file = paths.shift
      catch(:prune) do
        yield file.dup.taint
        next unless File.exist? file
        begin
          if File.lstat(file).directory? then
            d = Dir.open(file)
            begin
              for f in d
                next if f == "." or f == ".."
                if File::ALT_SEPARATOR and 
                file =~ /^(?:[\/\\]|[A-Za-z]:[\/\\]?)$/ then
                  f = file + f
                elsif file == "/" then
                  f = "/" + f
                else
                  f = File.join(file, f)
                end
                paths.unshift f.untaint
              end
            ensure
              d.close
            end
          end
        rescue Errno::ENOENT, Errno::EACCES
        end
      end
    end
  end
  
  def self.prune
    throw :prune
  end
  #--------------------------------------------------------------------------
  # * Kopiert Dateien -Ruby Standard Library
  #--------------------------------------------------------------------------
  BUFSIZE = 8 * 1024
  def self.catname(from, to)
    if directory? to
      join to.sub(%r([/\\]$), ''), basename(from)
    else
      to
    end
  end
  def self.syscopy(from, to)
    to = catname(from, to)
    fmode = stat(from).mode
    tpath = to
    not_exist = !exist?(tpath)
    from = open(from, "rb")
    to = open(to, "wb")
    begin
      while true do to.syswrite from.sysread(BUFSIZE) end
    rescue EOFError
      ret = true
    rescue
      ret = false
    ensure
      to.close
      from.close
    end
    chmod(fmode, tpath) if not_exist
    ret
  end
end
Teil 2

Code:
#==============================================================================
# ** Ressourcen - von KD
#------------------------------------------------------------------------------
#  Diese Klasse speichert Ressourcennamen und liest diese aus Projekten aus
#==============================================================================
class Ressourcen
  include(Enumerable)
  #--------------------------------------------------------------------------
  # * Konstanten
  #--------------------------------------------------------------------------
  ORDNER = "Data/"                  #Ordner wo die Daten sich befinden
  MAPS = "Map"                      #Dateiname der Maps
  ENDUNG = ".rxdata"                #Dateiendung der Daten 
  LOGPFAD = "/log/"                 #Pfad der Logdateien
  LOGNAME = "ressourcen"            #Dateiname der Logdatei
  LOGENDING = '.log'                #Dateiendung der Logdateien
  LOESCHPFAD = "/nicht_benoetigt/"  #Pfad für verschobene Ressourcendateien
  
  #Konstanten für den Automatik-Vorgang
  LOGGEN      = true      #Genutzte Ressourcen werden geloggt
  MULTI_FILE  = false     #Ressourcen werden in mehreren Textdateien geloggt
  LOG_UNUSED  = true      #Ungenutzte Ressourcen werden extra geloggt
  LOESCHEN    = false     #nicht benötigte Ressourcen werden gelöscht
  EXIT        = true      #Nach Ausführen des Vorgangs wird Programm beendet
  LOG_ORDNER  = '/unused/'#Logordner für ungenutzte Ressourcen
  UNUSEDNAME  = 'unused'  #Dateiname für ungenutzte-Ressourcenlogdatei
  #--------------------------------------------------------------------------
  # * Attribute
  #-------------------------------------------------------------------------- 
  METADIRECTORY = Hash.new
  METADIRECTORY['graphics'] = [:characters, :windowskins, :transitions,
             :fogs, :battlebacks, :panoramas, :windowskins, :characters,
             :animations, :autotiles, :battlers, :gameovers, :icons,
             :pictures, :tilesets, :titles]
  METADIRECTORY['audio'] = [:se, :bgs, :me, :bgm]
  TYPEN = METADIRECTORY.values.flatten
  #Attribut Readers -> Metadirectories, Typen, root
  METADIRECTORY.each_key {|meta| define_method(meta.to_sym) {
    result = Array.new
    METADIRECTORY[meta].each {|m| result << self.method(m).call}
    result.flatten
  }}
  attr_reader(:root, *TYPEN)
  #============================================================================
  #            ***Initialisierung der Instanzvariablen***
  #  root#String : Gibt den Pfad zum Projektordner an
  #============================================================================
  def initialize(root='.')
    TYPEN.each {|typ|
      self.instance_variable_set(typ.to_isym, Array.new)
    }
    @root = root
  end
  #============================================================================
  #                         ***Klassenmethoden***
  #============================================================================
  #--------------------------------------------------------------------------
  # * Definiert Dateiendungen für einen Typ o. Metaordner
  #  klassifizierung#String/Symbol : Metaordner oder Typ der Dateiendung
  #  *extensions#Strings : Name der Dateiendung
  #--------------------------------------------------------------------------
  @@extensions = Hash.new
  def self.extensions_for(klassifizierung, *extensions)
    k = klassifizierung.to_s.downcase
    if @@extensions[k] then
      @@extensions[k].add(extensions)
    else
      @@extensions[k] = extensions
    end
  end
  #--------------------------------------------------------------------------
  # * Erzeugt Dateiendungen
  #--------------------------------------------------------------------------
  extensions_for('audio', 'mid', 'ogg', 'wav', 'mp3', 'wma')
  extensions_for('graphics', 'png', 'bmp', 'jpg')
  #--------------------------------------------------------------------------
  # * Gib Dateiendungen für bestimmten Typ/Metaordner zurück => Array
  #  typ#String/Symbol : Metaordner oder Typ, der gesuchte Dateiendung hat
  #                      Standardmäßig werden alle Dateiendungen ausgegeben
  #--------------------------------------------------------------------------
  def self.extensions(typ=true)
    if (typ==true) then return @@extensions.values.flatten end
    key = typ.to_s.downcase
    if @@extensions.has_key?(key) then
      @@extensions[key]
    elsif @@extensions.has_key?(n=metadirectory_for(typ).to_s.downcase)
      @@extensions[n]
    else
      []
    end
  end
  def extensions(t=true); Ressourcen.extensions(t); end
  #--------------------------------------------------------------------------
  # * Gibt den Metaordner für einen Typ aus => nil oder String
  #  typ#Symbol : Typ, dessen Metaordner gesucht wird
  #--------------------------------------------------------------------------
  def self.metadirectory_for(typ)
    if typ then
      typ = typ.to_s.downcase.to_sym
      METADIRECTORY.key_for_value(typ) {|h, s| h.include?(s)}
    else
      nil
    end
  end
  def metadirectory_for(typ); Ressourcen.metadirectory_for(typ); end
  #--------------------------------------------------------------------------
  # * Sucht nach Ressourcen, loggt diese und löscht ggf. nicht benötigte
  #--------------------------------------------------------------------------
  def self.automatik()
    ressourcen = genutzte_ressourcen.sort!
    if MULTI_FILE then ressourcen.loggen else ressourcen.loggen_one end if LOGGEN
    if LOG_UNUSED or LOESCHEN then 
      unused = Ressourcen.ungenutzte_ressourcen(ressourcen)
    end
    if LOG_UNUSED then
      if MULTI_FILE then 
        unused.loggen(LOG_ORDNER) 
      else 
        unused.loggen_one(LOGPFAD, UNUSEDNAME)
      end
    end
    if LOESCHEN then unused.verschiebe end
    exit if EXIT
  end
  
  #--------------------------------------------------------------------------
  # * Erzeugt Construktor-Methoden
  #  methode#Symbol : Methode, für die ein Constructor erzeugt wird
  #--------------------------------------------------------------------------
  def self.constructor(methode)
    $methode = methode
    class << self; m = $methode; define_method(m) {|*a|
      root=if a[0].class==String and self.instance_method(m).arity.abs < a.size 
        a.shift else "." 
      end
      r = self.new(root)
      r.method(m).call(*a)
      r
    } end
    $methode = nil
  end
  #--------------------------------------------------------------------------
  # * Erzeugt Constructor und alternative Methodennamen
  #  name#Symbol : Methode, die behandelt wird
  #  *alternatives#Symbole : Alternative Methodennamen
  #--------------------------------------------------------------------------
  def self.constructor_and_alternatives(name, *alternatives)
    constructor(name) #erzeuge Konstructor für Methode
    link(name, *alternatives) #alternative namen für Methode
    link_classmethod(name, *alternatives) #alternative namen für Konstruktor
  end
  #============================================================================
  #              ***Constructor Methoden*** => Ressourcenobjekt
  #  Als Klassenmethoden genutzt erzeugen sie neue Ressourcen-Objekte
  #    root#String : Erzeugt ein Ressourcenobjekt in diesem Projektordner
  #  Als Instanzmethoden genutzt fügen sie dem Objekt neue Ressourcen hinzu
  #============================================================================
  #--------------------------------------------------------------------------
  # * Erzeugt ein Ressourcenobjekt aus genutzten Ressourcen eines Projektes
  #--------------------------------------------------------------------------
  def genutzte_ressourcen()
    durchsuche_maps
    durchsuche_database
    self
  end
  constructor_and_alternatives(:genutzte_ressourcen, :used_ressources)
  #--------------------------------------------------------------------------
  # *  Erzeugt ein Ressourcenobjekt aus importierten Ressourcen eines Projektes
  #--------------------------------------------------------------------------
  def importierte_ressourcen()
    pfad = @root + '/'
    #Durchsuche alle Metaordner
    directories = METADIRECTORY.keys.collect {|e| pfad + e.to_s}
    dirs = ""
    METADIRECTORY.keys.each {|d| dirs = dirs.concat('|' + d.to_s)}
    dirs = dirs.sub('|', '')
    pfad = ' ' + pfad
    while a = pfad =~ /[^\\]\./ do pfad[a+1] = '\\.'  end
    while a = pfad =~ /[^\\]\// do pfad[a+1] = '\\/'  end
    pfad[0] = ''
    regexp = Regexp.new(pfad+"(#{dirs})"+'\/(.+)\/(.+)\..+', true)
    File.find(*directories) {|pfad|
      #Wenn gefundene Datei die passende Dateiendung hat....
      pfad =~ regexp
      if File.ressource?(pfad.downcase, *extensions($2)) then
        #...soll sie in die Liste aufgenommen werden
        if method(methode=$2.downcase.to_sym) then
          method(methode).call.add($3)
        end
      end
    }
    self
  end
  constructor_and_alternatives(:importierte_ressourcen, :imported_ressources)
  #--------------------------------------------------------------------------
  # * Erzeugt ein Ressourcenobjekt aus nichtbenötigten Ressourcen des Projektes
  #  genutzte#Ressourcen : Prozess lässt sich beschleunigen, wenn das
  #                        genutzte-Ressourcenobjekt zuvor schon erzeugt wurde 
  #--------------------------------------------------------------------------
  def ungenutzte_ressourcen(genutzte=nil)
    genutzte = Ressourcen.genutzte_ressourcen(@root) unless genutzte
    importierte_ressourcen()
    drop(genutzte)
  end
  constructor_and_alternatives(:ungenutzte_ressourcen, :unused_ressources)
  #--------------------------------------------------------------------------
  # * Erzeugt ein Ressourcenobjekt aus einer Map
  #  mapdateiname#String : Pfad zur Mapdatei
  #--------------------------------------------------------------------------
  def durchsuche_map(mappfad)
    map = load_data(@root+'/'+mappfad)
    #Suche aus der Map alle Sounddateien heraus
    bgm.add(map.bgm.name) if map.autoplay_bgm
    bgm.add(map.bgs.name) if map.autoplay_bgs
    #Suche aus der Map alle Eventgrafiken heraus
    events = map.events
    events.each_value {|event|
      event.pages.each {|page|
        characters.add(page.graphic.character_name)
        #Suche alle Ressourcen aus MoveBefehlen heraus
        durchsuche_moveroute(page.move_route.list)
        #Suche alle Ressourcen aus Eventbefehlen heraus
        durchsuche_eventcommands(page.list)
      }
    }
    self
  end
  constructor_and_alternatives(:durchsuche_map, :scan_map)
  #--------------------------------------------------------------------------
  # * Erzeugt ein Ressourcenobjekt aus den Mapdaten
  #--------------------------------------------------------------------------
  def durchsuche_maps
    #Suche in den Maps nach verwendeten Ressourcen
    i = 1
    name = ORDNER + MAPS+i.zu_nstelligen_string(3)+ENDUNG
    while File.exist?(@root + "/" + name)
      durchsuche_map(name)
      i += 1
      name = ORDNER + MAPS+i.zu_nstelligen_string(3)+ENDUNG
    end
    self
  end
  constructor_and_alternatives(:durchsuche_maps, :scan_maps)
  #--------------------------------------------------------------------------
  # * Erzeugt ein Ressourcenobjekt aus den Move-Routes
  #  move_list#RPG::MoveCommand-Array : Move-Commands die durchsucht werden
  #--------------------------------------------------------------------------
  def durchsuche_moveroute(move_liste)
    move_liste.each {|befehl|
      case befehl.code
        when 41
          characters.add(befehl.parameters[0])
        when 44
          bgs.add(befehl.parameters[0].name)
        when 45
          durchsuche_script(befehl.parameters[0])
        end
    }
    self
  end
  constructor_and_alternatives(:durchsuche_moveroute, :scan_moveroute)
  #--------------------------------------------------------------------------
  # * Erzeugt ein Ressourcenobjekt aus den Event Commands
  #  liste#RPG::EventCommand-Array : EventCommands die durchsucht werden
  #--------------------------------------------------------------------------
  def durchsuche_eventcommands(liste)
    rubystring = ""
    messagestring = ""
    commentstring = ""
    liste.each {|befehl|
      case befehl.code
        when 101, 401
          messagestring += "\n" + befehl.parameters[0]
        when 108, 408
          commentstring += "\n" + befehl.parameters[0]
        when 111
          if befehl.parameters[4] == 12
            rubystring + "\n" + befehl.parameters[1]
          end
        when 131
          windowskins.add(befehl.parameters[0])
        when 132
          bgm.add(befehl.parameters[0].name)
        when 133
          me.add(befehl.parameters[0].name)
        when 204
          case befehl.parameters[0]
            when 0 then panoramas.add(befehl.parameters[1])
            when 1 then fogs.add(befehl.parameters[1])
            when 2 then battlebacks.add(befehl.parameters[1])
          end
        when 209
          durchsuche_moveroute(befehl.parameters[1].list)
        when 222
          transitions.add(befehl.parameters[0])
        when 231
          pictures.add(befehl.parameters[1])
        when 241
          bgm.add(befehl.parameters[0].name)
        when 245
          bgs.add(befehl.parameters[0].name)
        when 249
          me.add(befehl.parameters[0].name)
        when 250
          se.add(befehl.parameters[0].name)
        when 322
          characters.add(befehl.parameters[1])
          battlers.add(befehl.parameters[3])
        when 355
          rubystring.concat(befehl.parameters[0])
        when 655
          rubystring.concat(befehl.parameters[0])
      end
    }
    durchsuche_script(rubystring)
    durchsuche_message(messagestring)
    durchsuche_comment(commentstring)
    self
  end
  constructor_and_alternatives(:durchsuche_eventcommands, :scan_eventcommands)
  #--------------------------------------------------------------------------
  # * Erzeugt ein Ressourcenobjekt aus den Rubyscripts (unvollständig)
  #  string#String : String aus Rubyscripten, der durchsucht wird
  #--------------------------------------------------------------------------
  def durchsuche_script(string)
    self
  end
  constructor_and_alternatives(:durchsuche_script, :scan_script)
  #--------------------------------------------------------------------------
  # * Erzeugt ein Ressourcenobjekt aus den Messagescripts (unvollständig)
  #  string#String : String aus Messages, der durchsucht wird
  #--------------------------------------------------------------------------
  def durchsuche_message(string)
    self
  end
  constructor_and_alternatives(:durchsuche_script, :scan_script)
  #--------------------------------------------------------------------------
  # * Erzeugt ein Ressourcenobjekt aus den Commentcripts (unvollständig)
  #  string#String : String aus Comments, der durchsucht wird
  #--------------------------------------------------------------------------
  def durchsuche_comment(string)
    self
  end
  constructor_and_alternatives(:durchsuche_script, :scan_script)
  #--------------------------------------------------------------------------
  # * Erzeugt ein Ressourcenobjekt aus den Informationen der Database
  #--------------------------------------------------------------------------
  def durchsuche_database
    #Actors
    datei = load_data("#{@root}/Data/Actors.rxdata")
    datei.each {|actor|
      next unless actor
      characters.add(actor.character_name)
      battlers.add(actor.battler_name)
    }
    #Skills und Items
    datei = load_data("#{@root}/Data/Skills.rxdata") +
      load_data("#{@root}/Data/Items.rxdata")
    datei.each {|e|
      next unless e
      icons.add(e.icon_name)
      se.add(e.menu_se.name)
    }
    #Weapons und armors
    datei = load_data("#{@root}/Data/Weapons.rxdata") +
      load_data("#{@root}/Data/Armors.rxdata")
    datei.each {|e| 
      next unless e
      icons.add(e.icon_name)
    }
    #Enemies
    datei = load_data("#{@root}/Data/Enemies.rxdata")
    datei.each {|e| 
      next unless e
      battlers.add(e.battler_name)
    }
    #Battle-Events
    datei = load_data("#{@root}/Data/Troops.rxdata")
    datei.each {|e|
      next unless e
      e.pages.each {|page|
        durchsuche_eventcommands(page.list)
      }
    }
    #Animations
    datei = load_data("#{@root}/Data/Animations.rxdata")
    datei.each {|e|
      next unless e
      animations.add(e.animation_name)
      e.timings.each {|time| se.add(time.se.name)}
    }
    #Tilesets
    datei = load_data("#{@root}/Data/Tilesets.rxdata")
    datei.each {|e|
      next unless e
      tilesets.add(e.tileset_name)
      autotiles.add(*e.autotile_names)
      panoramas.add(e.panorama_name)
      fogs.add(e.fog_name)
      battlebacks.add(e.battleback_name)
    }
    #CommonEvents
    datei = load_data("#{@root}/Data/CommonEvents.rxdata")
    datei.each {|e| 
      next unless e
      durchsuche_eventcommands(e.list)
    }
    #System
    datei = load_data("#{@root}/Data/System.rxdata")
    windowskins.add(datei.windowskin_name)
    titles.add(datei.title_name)
    gameovers.add(datei.gameover_name)
    windowskins.add(datei.windowskin_name)
    transitions.add(datei.battle_transition)
    bgm.add(datei.title_bgm.name)
    bgm.add(datei.battle_bgm.name)
    me.add(datei.battle_end_me.name)
    me.add(datei.gameover_me.name)
    se.add(datei.cursor_se.name)
    se.add(datei.decision_se.name)
    se.add(datei.cancel_se.name)
    se.add(datei.buzzer_se.name)
    se.add(datei.equip_se.name)
    se.add(datei.shop_se.name)
    se.add(datei.save_se.name)
    se.add(datei.load_se.name)
    se.add(datei.battle_start_se.name)
    se.add(datei.escape_se.name)
    se.add(datei.actor_collapse_se.name)
    se.add(datei.enemy_collapse_se.name)
    battlebacks.add(datei.battleback_name)
    battlers.add(datei.battler_name)
    self
  end
  constructor_and_alternatives(:durchsuche_database, :scan_database)
  #============================================================================
  #                     ***Öffentliche Instanzmethoden***
  #============================================================================
  #--------------------------------------------------------------------------
  # * Sortiert ein Ressourcenobjekt => Ressourcen
  #--------------------------------------------------------------------------
  def sort!
    TYPEN.each {|typ|
      array = self.instance_variable_get(typ.to_isym)
      array.sort!
    }
    self
  end
  #--------------------------------------------------------------------------
  # * Gibt jene Ressourcentypen zurück, die nicht leer sind => Symbol-Array
  #--------------------------------------------------------------------------
  def typen
    TYPEN.find_all {|t| !self.instance_variable_get(t.to_isym).empty?}
  end
  #--------------------------------------------------------------------------
  # * Addition zweier Ressourcenobjekte => Ressourcen
  #  other#Ressourcen : Summant, mit dem das Ressourcenobjekt addiert wird
  #--------------------------------------------------------------------------
  def concat(other)
    TYPEN.each {|typ| 
      typ = typ.to_isym
      self.instance_variable_get(typ).add(*other.instance_variable_get(typ))
    }
    self
  end
  #--------------------------------------------------------------------------
  # * Subtraktion zweier Ressourcenobjekte => Ressourcen
  #  other#Ressourcen : Subtrahend , mit dem subtrahiert wird
  #--------------------------------------------------------------------------
  def drop(other)
    TYPEN.each {|typ| 
      typ = typ.to_isym
      v = self.instance_variable_get(typ) - other.instance_variable_get(typ)
      self.instance_variable_set(typ, v)
    }
    self
  end
  #--------------------------------------------------------------------------
  # * Schnittmenge zweier Ressourcenobjekte => Ressourcen
  #  other#Ressourcen : Vergleichsressourcenobjekt
  #--------------------------------------------------------------------------
  def compare(other)
    ressi = Ressourcen.new(@root)
    TYPEN.each {|typ| ressi.method(typ).call.add(
      *method(typ).call & other.method(typ).call)
    }
    ressi
  end
  #--------------------------------------------------------------------------
  # * Loggt die Ressourcen in verschiedenen Textdateien
  #  ordner#String : Pfad zum Log-Ordner
  #  dateiende#String : Dateiende der Logdateien
  #--------------------------------------------------------------------------
  def loggen(ordner=LOGPFAD, dateiende=LOGENDING)
    File.makedirs(@root + '/' + ordner)
    TYPEN.each {|typ|
      liste = self.instance_variable_get(typ.to_isym)
      next if liste.empty?
      File.open(path + ordner + typ.to_s + dateiende, 'w+') {|file|
        liste.each {|name|
          file.write(name + "\n")
        }
      }
    }
  end
  #--------------------------------------------------------------------------
  # * Loggt die Ressourcen in einer Textdatei
  #  ordner#String : Pfad zum Log-Ordner
  #  dname#String : Name der Logdatei
  #  dateiende#String : Dateiende der Logdatei
  #--------------------------------------------------------------------------
  def loggen_one(ordner=LOGPFAD, dname=LOGNAME, dateiende=LOGENDING)
    File.makedirs(@root+'/' + ordner)
    sortierer = Proc.new {|a,b| a.to_s <=> b.to_s}
    File.open(@root + '/' + ordner + dname + dateiende, 'w+') {|file|
      TYPEN.sort(&sortierer).each {|typ|
        liste = self.instance_variable_get(typ.to_isym)
        next if liste.empty?
        file.write(typ.to_s.capitalize + "\n")
        liste.each {|name|
          file.write(name + "\n")
        }
        file.write("\n")
      }
    }
  end
  #--------------------------------------------------------------------------
  # * Erzeugt die Ordner und ermitteln dest und src Pfade (Privat!)
  #--------------------------------------------------------------------------
  def ordner_erzeugen(path, *args, &block)   
    #Iteriere jeden Metaordner
    METADIRECTORY.each_pair {|ordner, typen|
      next if method(ordner.to_sym).call.empty?
      #Lege einen Ordner für diesen META an, falls noch nicht geschehen
      File.makedirs(dest_pfad = (path+'/'+ordner.capitalize))
      src_pfad = @root + '/' + ordner.capitalize
      #Iteriere die Typen jedes Metaordners
      typen.each {|typ|
        next if (inhalt=method(typ).call).empty?
        styp = typ.to_s.capitalize
        #Lege einen Ordner für diesen Typ an, falls noch nicht geschehen
        File.makedirs(dest_typpfad = dest_pfad + '/' + styp)
        src_typpfad = src_pfad + '/' + styp
        #Iteriere die Ressourcen eines Types
        inhalt.each {|e|
          #Ermittle vollständigen Dateinamen der Ressource
          src_name = src_typpfad + "/" + e
          endung = ""
          next if Ressourcen.extensions(typ).each {|endung|
            if File.exist?(src_name + '.' + endung) then break end
          }
          src_name = src_name + '.' + endung
          dest_name = dest_typpfad + '/' + e + '.' + endung
          #Führe den Proc aus
          block.call(src_name, dest_name, *args) 
        }
      }
    }
  end
  private(:ordner_erzeugen)
  #--------------------------------------------------------------------------
  # * Verschiebt Ressourcen in einen extra Ordner
  #  lpfad#String : Pfad zum Ordner, zu dem verschoben wird
  #--------------------------------------------------------------------------  
  def verschiebe(lpfad=LOESCHPFAD)
    lpfad = lpfad.root if lpfad.instance_of?(Ressourcen)
    ordner_erzeugen(@root + '/' + lpfad) {|src, dest| 
      File.rename(File.expand_path(src), File.expand_path(dest))
    }
  end
  link(:verschiebe, :move)
  #--------------------------------------------------------------------------
  # * Kopiert Ressourcen in ein anderes Projekt
  #  zielpfad#String/Ressourcen : Zielordner, in das Ressourcen kopiert werden
  #                               Ressourcenobjekt, in dessen Root kopiert wird 
  #-------------------------------------------------------------------------- 
  def kopiere(zielpfad)
    zielpfad = zielpfad.root if zielpfad.instance_of?(Ressourcen)
    ordner_erzeugen(zielpfad) {|src, dest|
      File.syscopy(File.expand_path(src), File.expand_path(dest))
    }
  end
  #--------------------------------------------------------------------------
  # * Erhält Größe der Ressourcendateien => String o. Float
  #--------------------------------------------------------------------------
  def size(special=false) #=> gibt Float zurück
    groesse = 0
    self.each(special) {|r| groesse += FileTest.size(path(r)) }
    groesse.to_f
  end
  def printable_size(special=false) #=> gibt einen lesbaren String zurück
    size(special).datasize
  end
  #--------------------------------------------------------------------------
  # * Sucht Pfad einer Datei => String
  # name#String : Name der gesuchten Datei
  # typ#Symbol : Typ der gesuchten Datei
  # meta#String : Metaordner, in dem sich die Datei befindet
  # endung#String : Endung der Datei
  # Angaben bis auf name können weggelassen werden, verzögern aber den Prozess
  #--------------------------------------------------------------------------
  def path(name, typ=false, meta=false, endung=false)
    dmeta = if meta then meta elsif typ then meta(typ) else meta(name) end
    dtyp = (if typ then typ else typ(name) end).to_s
    return false unless (dmeta and dtyp)
    path = "#{@root}/#{dmeta}/#{dtyp}/#{name}"
    dendung = if endung then endung else endung(name, dtyp.to_sym, dmeta) end
    return false unless dendung
    path + '.' + dendung
  end
  #--------------------------------------------------------------------------
  # * Sucht Metaordner einer Datei => String
  #  angabe#String/Symbol: Entweder Dateiname oder Dateityp
  #-------------------------------------------------------------------------- 
  def meta(angabe)
    typ = if TYPEN.include?(angabe.to_sym) then angabe else typ(angabe) end
    Ressourcen.metadirectory_for(typ)
  end
  #--------------------------------------------------------------------------
  # * Sucht Typ einer Datei => Symbol
  #  name#String: Dateiname
  #-------------------------------------------------------------------------- 
  def typ(name)
    typ = nil
    if (TYPEN.each {|typ| break if method(typ).call.include?(name)}).nil? then
      typ else nil end
    end
  #--------------------------------------------------------------------------
  # * Sucht Endung einer Datei => String
  #  name#String : Dateiname
  #  typ#Symbol : Typ der gesuchten Datei
  #  meta#String : Metaordner der Datei
  # Angaben bis auf name können weggelassen werden, verzögern aber den Prozess
  #-------------------------------------------------------------------------- 
  def endung(name, typ=false, meta=false)
    typ = typ(name) unless typ
    meta = meta(typ) unless meta
    path = "#{@root}/#{meta}/#{typ}/#{name}"
    e = nil
    if (Ressourcen.extensions(typ).each {|e|
        if File.exist?(path + '.' + e) then break end
      }) then nil else e 
    end
  end
  #--------------------------------------------------------------------------
  # * Gibt alle Pfade aus, die den Angaben entsprechen => String-Array
  #  dname#String: Dateiname; dtyp#Symbol : Dateityp; dmeta#String : Metaordner
  #  dendung#String : Endung der Datei
  # Wenn Angaben weggelassen werden, werden alle Pfade ausgegeben
  # Wenn Block angegeben, werden die einzelnen Pfade iteriert
  #--------------------------------------------------------------------------
  def paths(dname=false, dtyp=false, dmeta=false, dendung=false)
    typen = if dtyp then dtyp.to_a
      elsif dmeta then METADIRECTORY[dmeta]
      else typen()
    end
    result = Array.new
    typen.each {|typ|
      method(typ).call.each {|name| 
        if dendung or (dendung = endung(name, typ)) then
          result << path(name, typ, false, dendung)
        end
      }
    }
    result.each{|e| yield(e)} if block_given?
    result
  end
  #--------------------------------------------------------------------------
  # * Iteriert Ressourcennamen (Enumerable Modul)
  #  special#Symbol/String : Nur Inhalt des Metaordners/Typs wird iteriert
  #  Wenn kein special angegeben, wird jeder Ressourcenname iteriert
  #-------------------------------------------------------------------------- 
  def each(special=false, &block)
    if special then 
      self.method(special.to_sym).call.each(&block)
    else 
       (TYPEN.collect {|typ| self.method(typ).call}).flatten.each(&block)
    end
  end
end