Blog

  • Gyms

    Wwise Gyms

    Wwise™ Gyms

    The Wwise Gyms are examples and tests for both the Unreal™ and Unity™ Wwise™ Integrations.

    Supported versions

    The Gym projects support the major version of Wwise indicated in the current git branch, as well as its minor versions. The following software versions are supported:

    • Wwise™ 2023.1 and all minor releases
    • The latest three Unity™ LTS versions
    • The latest three Unreal™ versions

    Setup

    The Gyms do not include the Wwise Integration of their engine. Use the Wwise Launcher to integrate Wwise into both projects. In the WwiseProject folder, run GenerateProjectWavFiles.py. Open the Wwise Project in Wwise and generate the SoundBanks. Alternatively, you can run the setup.bat file for your platform.

    Unreal

    With the Wwise Gyms for Unreal, make sure to set the version of the uproject before you integrate the project through the Audiokinetic Launcher. To change the uproject version, right-click Gyms.uproject and select Switch Unreal Engine Version.

    Unity

    With the Wwise Gyms for Unity, select Install files directly into the Unity project directory when you are integrating Wwise. Refer to Integrating Wwise into a Unity Project for details.

    Aditional Requirements

    In order to generate the Wwise WAV files, you need to install a Python 3 interpreter, as well as the NumPy package. The NumPy package can be compiled from source or installed through package managers. For example, you can use pip to install NumPy by calling pip install numpy. Refer to the NumPy install page for more information.

    Project Documentation

    Legal

    Wwise Gyms are released under dual license with Apache 2.0.

    Visit original content creator repository https://github.com/audiokinetic/Gyms
  • duplication

    Duplication

    This small script creates backups of files existing in a specific location by copying them to to one or more other locations. Since this is meant to duplicate backups, changes to files are not checked for. All remote file reads are cached locally to minimize traffic while the script runs.

    Installation

    Clone this repository to a machine you own. Then use composer install to install the dependencies.

    Configuration

    Please copy the supplied config.example.yml to config.yml and adjust the values as required. We are using Contabo, this may or may not work with other storage providers.

    Type SSH

    This will use sftp to connect to a server. This can be used for upload and download.

    Read

    type: ssh
    user: rotten
    ssh-path: /backups
    host: test-01.idrinth.de
    password: abcdefghijklmnopqrstuvwxyz
    private-key: /private/key.pem
    port: 22
    encrypt-with-public-key: true
    minify: false

    Write

    type: ssh
    bucket-path: /backups
    user: rotten
    ssh-path: /backups
    host: test-01.idrinth.de
    password: abcdefghijklmnopqrstuvwxyz
    private-key: /private/key.pem
    force-date-prefix: false
    prefix: backups
    port: 22

    Type Local

    This will back up from or on the local machine.

    Read

    type: local
    path: /backups
    encrypt-with-public-key: true
    minify: false

    Write

    type: local
    path: /backups
    user: backup
    group: backup
    prefix: mine
    force-date-prefix: false

    Type Bucket

    This uses an S3 bucket to read from or write to.

    Read

    type: bucket
    endpoint: buckets.idrinth.de/test-01
    bucket: test-01
    access-key: abcdefghijklmnopqrstuvwxyz
    secret-access-key: 1234567890
    encrypt-with-public-key: true
    minify: false

    Write

    type: bucket
    endpoint: buckets.idrinth.de/test-01
    bucket: test-01
    access-key: abcdefghijklmnopqrstuvwxyz
    secret-access-key: 1234567890
    force-date-prefix: false

    Support

    If you need support, got an improvement idea or want to chat about the project, feel free to open an issue or join the discord.

    Visit original content creator repository
    https://github.com/Idrinth/duplication

  • MediaPlayer

    MediaPlayer for Android

    Project API Bower

    一个现代化的Android 本地音乐播放器,使用Java 开发

    See

    Soft.clear(v->Bug.search(v.getMessage()).isBug());
    
    
    _______________________________________________
    _______________________________________________
    ________________########_______________________
    _______________##########______________________
    ______________############_____________________
    ______________#############____________________
    _____________##__###########___________________
    ____________###__######_#####__________________
    ____________###_#######___####_________________
    ___________###__##########_####________________
    __________####__###########_####_______________
    ________#####___###########__#####_____________
    _______######___###_########___#####___________
    _______#####___###___########___######_________
    ______######___###__###########___######_______
    _____######___####_##############__######______
    ____#######__#####################_#######_____
    ____#######__##############################____
    ___#######__######_#################_#######___
    ___#######__######_######_#########___######___
    ___#######____##__######___######_____######___
    ___#######________######____#####_____#####____
    ____######________#####_____#####_____####_____
    _____#####________####______#####_____###______
    ______#####______;###________###______#________
    ________##_______####________####______________
    

    License

    Copyright (c) 2013, Aldo Cortesi. All rights reserved.
    
    Permission is hereby granted, free of charge, to any person obtaining a copy
    of this software and associated documentation files (the "Software"), to deal
    in the Software without restriction, including without limitation the rights
    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    copies of the Software, and to permit persons to whom the Software is
    furnished to do so, subject to the following conditions:
    
    The above copyright notice and this permission notice shall be included in
    all copies or substantial portions of the Software.
    
    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
    SOFTWARE.
    
    Visit original content creator repository https://github.com/ExplodingDragon2/MediaPlayer
  • Computer-Benchmark

    Computer-Benchmark

    Analyzing the performance of my custom built PC using a variety of gaming and synthetic benchmarks.

    Compiling Data

    I measured several variables as I tested my computer (such as but not limited to GPU/CPU temperature, power draw, utilization, and clock speed) to see if my PC was performing as I’d expect for the components I bought. In addition, getting a baseline performance analysis of my computer will help me in the future if something starts to act up on my computer. For example, I’ll have a good idea when my the thermal compound on my CPU cooler needs to be replaced once the CPU starts going significantly above the baseline temperature I measured while all the components were new.

    The two programs I used to measure these variables were Nvidia’s Frameview and HWiNFO64 which saved the data as CSV’s that I could then import into R.

    In the case of frameview, the program created a new CSV file for every game tested with the name of the game being included in the CSV’s file name. So, instead of manually compiling each of the separate game files together I built a python program called “Organize Excel” to automatically sort through all the CSV files in the frame view folder and combine them together as individual sheets within a single excel file for easy analysis in R.

    I compiled all the data I collected into line and bar graphs using ggplot2 in R.

    Gaming Benchmarks

    My current test suit of games includes: GTAV, Overwatch, Rainbow Six Siege, Apex Legends, Destiny 2, Rocket League, Battlefront 2, Halo Infinite, Fortnite, and Call of Duty: Warzone. For each game I examined the following variables as I ran my benchmark: Frametime, GPU and CPU temperature, GPU and CPU utilization, GPU and CPU clock speed, GPU and CPU power consumption, Fan speed for CPU & GPU coolers, fan speed for the case fans, and Average FPS, 1% low FPS, and .1% low FPS. Analysis and graphs made for the gaming test suite was this was done in the “neat_game” program.

    For all the variables above except Average FPS, 1% low FPS, and .1% low FPS each game was tested one time. For the Average FPS, 1% low FPS, and .1% low FPS I tested each game three times and then averaged the results together to get a more accurate measure of real world FPS while playing games.

    Synthetic Benchmarks

    The synthetic benchmarks I tested with are 3D Mark’s Timespy and Fire Strike Extreme, Heaven, and Cinebench R23. I tested the same variables with the synthetic benchmarks as I did with games except I did not measure frametime or any FPS measure. Analysis and graphs made for synthetic benchmarks test suite was this was done in the “neat_synthetic” program.

    Sorting Graphs by Name

    Once all the graphs from the “neat_game” and “neat_synthetic” programs were made and automatically saved into their specific “unsorted” folders, I used built a python program called “Graph File Organization” to sort each graph into relevant folders designated by the specific game/synthetic benchmark name.

    More Information

    For more information on the configuration and specifications of my computer please see the document titled “Computer info -July 1 Tests.docx”.

    “Problems are opportunities in disguise.” – Charles F. Kettering

    Visit original content creator repository
    https://github.com/Ryan-Iacovone/Computer-Benchmark

  • splendidbacon

    Splendid Bacon

    Project Management* for hackers

    Caveats

    There are a few issues that should be fixed before taking this into production use:

    • Fix the mass assignment vulnerabilities (this is the most important thing)
      • config.active_record.mass_assignment_sanitizer = :strict
      • config.active_record.whitelist_attributes = true

    Note: Any API keys included in the source code have been revoked and cannot be used.

    Installation (for development)

    1. Clone the repository

      git clone git@github.com:kiskolabs/splendidbacon.git

    2. Check that you have the right ruby version (> 1.9.2)

    3. Install the required gems

      bundle install

      in development you might want to also pass --without production

    4. Create database.yml in the config folder. You can cp config/database.example.yml config/database.yml to get a starting point.

    5. Create the .env file. You can cp sample.env .env to get a starting point.

    6. Setup the database (create DB, load schema, load seed data)

      rake db:setup

    7. Start the app

      foreman start

    The admin console is located at http://localhost:5000/magic

    NB. The session secret must be set as an environment variable called SECRET_TOKEN.

    You can generate a new secret with rake secret.

    On Heroku, you can set the session secret with this one-liner:

    heroku config:add SECRET_TOKEN=\`rake secret`
    

    Foreman is included to make managing environment variables easier in development. Include any environment variables you need in a .env file (see sample.env as a reference).

    Tests Build Status

    Run the test suite with:

    bundle exec rake spec
    

    Or:

    bundle exec rspec spec
    

    License and Copyright

    Copyright © 2010-2012 Kisko Labs & contributors.

    Licensed under the MIT license. See the LICENSE file for the full license text.

    Visit original content creator repository
    https://github.com/kiskolabs/splendidbacon

  • Flexinets.Radius.Core

    Radius packet parser and assembler library for .Net.

    Includes Core functionality for parsing and assembling Radius packets using a dictionary

    Conditionally compliant with RFCs
    https://tools.ietf.org/html/rfc2865
    https://tools.ietf.org/html/rfc2866
    https://tools.ietf.org/html/rfc5997

    Projects

    Flexinets.Radius.Core

    Radius protocol bits and pieces. Published to NuGet here:
    https://www.nuget.org/packages/Flexinets.Radius.Core/

    Flexinets.Radius.Core.Tests

    Tests…

    Flexinets.Radius.TestClient

    Contains a minimal client which can be used to send test packets

    Flexinets.Radius.TestServer

    Contains a minimal server for responding with a static username and password with basic attributes

    BlastRadius support

    To support communication with Radius servers or clients enforcing Blast Radius checks, a Message-Authenticator must be added to sent packets and validated when received.

    // Sending a packet
    var requestPacket = new RadiusPacket(PacketCode.AccessRequest, 0, "xyzzy5461");
    requestPacket.AddMessageAuthenticator(); // Add message authenticator for blast radius
    requestPacket.AddAttribute("User-Name", "nemo");
    requestPacket.AddAttribute("User-Password", "arctangent");

    When receiving response packets, the request packet Authenticator must be passed to IRadiusPacketParse.Parse in order to calculate the correct Message-Authenticator in the response
    When receiving request packets, the Message-Authenticator is required and validated by default for all Access* packets in version 3.0.0 and greater.

    In version 2.0.1 Blast radius checks can be enabled by setting skipBlastRadiusChecks to False when creating a RadiusPacketParser.

    /// Set skipBlastRadiusChecks when creating packet parser
    var radiusPacketParser new RadiusPacketParser(
            loggerFactory.CreateLogger<RadiusPacketParser>(),
            RadiusDictionary.Parse(DefaultDictionary.RadiusDictionary),
            skipBlastRadiusChecks: false)   // Default 'false' in version >= 3.0.0 and 'true' in 2.0.1
    
    /// ...
    
    // Receiving a packet
    var parsedPacket = radiusPacketParser.Parse(
                        reponsePacketBytes,
                        requestPacket.SharedSecret,
                        requestPacket.Authenticator); // <- corresponding request Authenticator

    Visit original content creator repository
    https://github.com/vforteli/Flexinets.Radius.Core

  • Roundcube

    Roundcube

    Note

    • The Reason How I Wrote This Article I've Seen It On A Few Government Sites

    Example Directories

    • roundcube/temp
    • /webmail/temp
    • /mail/temp
    • /temp

    Example URL

    • webmail.localhost.com/temp
    • mail.localhost.com/temp
    • webmail.localhost.com/webmail/temp
    • webmail.localhost.com/mail/temp
    • mail.localhost.com/webmail/temp
    • localhost.com/webmail/temp
    • localhost.com/mail/temp
    • webmail.localhost.com/roundcube/temp
    • mail.localhost.com/roundcube/temp
    • localhost.com/roundcube/temp

    Title

    “Preventing Document Leaks in Roundcube Webmail: Addressing the Vulnerability in the /temp Directory”.

    Brief Summary

    • The article discusses a vulnerability in the popular Roundcube webmail platform related to the /temp directory. The /temp directory is used to store temporary files, including email attachments that may contain sensitive information. The vulnerability is related to the fact that the /temp directory is not protected by the 403 Forbidden error response, which means anyone with access to the server could potentially gain access to the attachments stored in the directory, resulting in a data breach. The article explains the possible consequences of a document leak, which include identity theft, financial loss, and legal liabilities for individuals and organizations. The article provides a simple fix to address the

    Write-ups

    • Roundcube Webmail is a popular open-source webmail application used by many individuals and organizations around the world. It provides a range of features, including email composition and reading, address book management, and message filtering. However, like any software, Roundcube Webmail can be vulnerable to security threats if not properly configured.

    • One of the security threats that can impact Roundcube Webmail is the theft of files from the /temp directory. The /temp directory is a temporary directory that Roundcube Webmail uses to store files that are uploaded or generated during user sessions. By default, this directory is not secured and can be accessed by anyone who has access to the web server hosting the application.

    • If the /temp directory is not properly secured, attackers can easily access and steal files that have been uploaded or generated by users. For example, if a user uploads a file containing sensitive information, such as a password or financial data, an attacker can easily access and steal that file from the /temp directory. This can lead to serious security breaches and data loss.

    • To prevent file theft from the /temp directory, it is important to properly secure the directory. One way to do this is to set appropriate permissions on the directory to restrict access. This can be done by setting the appropriate file permissions or by configuring the web server to restrict access to the directory.

    • Another way to secure the /temp directory is to use a different directory altogether. For example, you can configure Roundcube Webmail to use a different directory for storing temporary files, which is not accessible to the public.

    • It is important to note that securing the /temp directory is just one aspect of securing Roundcube Webmail. There are other security threats that the application may be vulnerable to, and it is important to implement a comprehensive security plan to protect against them.

    • In conclusion, the /temp directory in Roundcube Webmail can be vulnerable to security threats if not properly secured. Attackers can easily access and steal files from the directory, which can lead to serious security breaches and data loss. Therefore, it is important to properly secure the directory by setting appropriate permissions or using a different directory altogether. Additionally, implementing a comprehensive security plan is necessary to protect against other potential security threats.

    Write-ups

    • Document Leaks in Roundcube Webmail: Addressing the Vulnerability in the /temp Directory

    • Roundcube is a popular webmail platform that has been widely used by individuals and organizations for email communication. However, it has been recently discovered that there is a vulnerability in the Roundcube software that could result in document leaks. This vulnerability is related to the /temp directory, which is not protected by the 403 Forbidden error response, as it should be.

    • In this article, we will discuss the significance of the /temp directory and why it should be protected, the possible consequences of a document leak, and how to address the vulnerability in the Roundcube software.

    • The Significance of the /temp Directory

    • The /temp directory is used to store temporary files that are generated by Roundcube during various processes. This includes attachments that are uploaded and downloaded through the webmail platform. These attachments could contain sensitive information such as confidential business documents, personal financial information, and sensitive communication.

    • If the /temp directory is not protected by the 403 Forbidden error response, anyone with access to the server could potentially gain access to the attachments stored in the directory. This could result in a data breach, which could have serious consequences for both individuals and organizations.

    • The Consequences of a Document Leak

    • A document leak can have a range of consequences, depending on the nature of the information that has been leaked. For individuals, this could result in identity theft, financial loss, and loss of privacy. For organizations, a document leak could result in loss of competitive advantage, reputational damage, and legal liabilities.

    • In addition, a document leak could also result in compliance violations, such as those related to data protection regulations such as the General Data Protection Regulation (GDPR) in the European Union or the California Consumer Privacy Act (CCPA) in California. Organizations could face substantial fines if they are found to be in violation of these regulations.

    • Addressing the Vulnerability in Roundcube

    • The vulnerability in the Roundcube software can be addressed by applying a simple fix to the code. The fix involves adding the 403 Forbidden error response to the /temp directory, which will prevent unauthorized access to the attachments stored in the directory.

    • To implement this fix, follow the steps below:

    • Open the .htaccess file in the /temp directory.

    • Add the following lines of code to the file:

    Order deny,allow
    Deny from all

    • Save and close the .htaccess file.

    • Restart the web server for the changes to take effect.

    • By applying this fix, organizations and individuals using Roundcube can significantly reduce the risk of a document leak.

    • Conclusion

    • Roundcube is a widely used webmail platform, and it is important to address any vulnerabilities that could result in document leaks. By not protecting the /temp directory with the 403 Forbidden error response, the attachments stored in the directory could be vulnerable to unauthorized access. By applying the simple fix discussed in this article, organizations and individuals can significantly reduce the risk of a data breach and the associated consequences.

    Visit original content creator repository
    https://github.com/0x01369/Roundcube

  • webchat-golang-socketio

    webchat-golang-socket.io

    It shows a chat application in which socket.io is used to connect server and client. Also, It supports 1-to-1 and groupchat using channel based communication. In this project, PUBSUB structure was deployed to support Say, Join and Leave.

    The server has a strangth to support massive traffics where the number of members is huge in a chatroom. It is different with mobile text application since delivery and display notifications are not required since all members basically show a chatroom together as well as Slack.

    RUN

    $ go get github.com/nkovacs/go-socket.io 
    $ go run main.go

    Docker Build

    $ docker build -t webchat-golang:v1 .

    Result

    • socket.io provide stable connection between server and client

    • Participant lists are listed on the top

    • User name is updated automatically without duplication

    image

    Data Structure

    Event

    type Event struct {
    	EvtType   string
    	User      string
    	Timestamp int
    	Text      string
    }

    Subscription

    type Subscription struct {
    	Archive []Event
    	New     <-chan Event
    }

    Message Data Structure

    type Message struct {
    	User      string
    	Timestamp int
    	Message   string
    }

    Chatroom Management

    func Chatroom() {
    	archive := list.New()
    	subscribers := list.New() // participants
    
    	for {
    		select {
    		case c := <-subscribe:
    			var events []Event
    
    			// If there are archived events
    			for e := archive.Front(); e != nil; e = e.Next() {
    				events = append(events, e.Value.(Event))
    			}
    
    			subscriber := make(chan Event, 10)
    			subscribers.PushBack(subscriber)
    
    			c <- Subscription{events, subscriber}
    
    		case event := <-publish:
    			for e := subscribers.Front(); e != nil; e = e.Next() {
    				subscriber := e.Value.(chan Event)
    				subscriber <- event
    			}
    
    			// at least 5 events were stored
    			if archive.Len() >= 5 {
    				archive.Remove(archive.Front())
    			}
    
    			archive.PushBack(event)
    
    		case c := <-unsubscribe:
    			for e := subscribers.Front(); e != nil; e = e.Next() {
    				subscriber := e.Value.(chan Event)
    
    				if subscriber == c {
    					subscribers.Remove(e)
    					break
    				}
    			}
    		}
    	}
    }

    Channel Management

    server.On("connection", func(so socketio.Socket) {
    		log.D("connected... %v", so.Id())
    
    		newMessages := make(chan string)
    
    		s := Subscribe()
    
    		so.On("join", func(user string) {
    			log.D("Join...%v (%v)", user, so.Id())
    
    			Join(user) // Join notification
    			userMap[so.Id()] = user
    
    			// if there are archived events
    			for _, event := range s.Archive {
    				so.Emit("chat", event)
    			}
    		})
    
    		so.On("chat", func(msg string) {
    			newMessages <- msg
    		})
    
    		so.On("disconnection", func() {
    			log.D("disconnected... %v", so.Id())
    
    			user := userMap[so.Id()]
    			delete(userMap, so.Id())
    
    			Leave(user) // left notifcation
    			s.Cancel()
    
    			// update participant lists
    			str := getParticipantList(userMap)
    			userStr = str
    			log.D("Update Participantlist: %v", userStr)
    			so.Emit("participant", userStr)
    		})
    
    		go func() {
    			for {
    				select {
    				case event := <-s.New: // send event to browser
    					so.Emit("chat", event)
    
    					// update participant lists
    					if event.EvtType == "join" || event.EvtType == "leave" {
    						str := getParticipantList(userMap)
    						userStr = str
    						log.D("Update Participantlist: %v", userStr)
    						so.Emit("participant", userStr)
    					}
    
    				case msg := <-newMessages: // received message from browser
    					var newMSG Message
    					json.Unmarshal([]byte(msg), &newMSG)
    
    					Say(newMSG)
    				}
    			}
    		}()
    	})

    Join

    func Join(user string) {
    	timestamp := time.Now().Unix()
    	publish <- NewEvent("join", user, int(timestamp), "")
    }

    Say

    func Join(user string) {
    	timestamp := time.Now().Unix()
    	publish <- NewEvent("join", user, int(timestamp), "")
    }

    Leave

    func Leave(user string) {
    	timestamp := time.Now().Unix()
    	publish <- NewEvent("leave", user, int(timestamp), "")
    }

    Troubleshooting – CORS

    In order to excape CORS, the header of Access-Control-Allow-Origin was appended as bellow.

        http.HandleFunc("/socket.io/", func(w http.ResponseWriter, r *http.Request) {
    		// origin to excape Cross-Origin Resource Sharing (CORS)
    		if origin := r.Header.Get("Origin"); origin != "" {
    			w.Header().Set("Access-Control-Allow-Origin", origin)
    		}
    		w.Header().Set("Access-Control-Allow-Credentials", "true")
    
    		server.ServeHTTP(w, r)
    	})

    Reference

    https://github.com/socketio/socket.io

    https://github.com/iamshaunjp/websockets-playlist

    https://github.com/nkovacs/go-socket.io

    https://github.com/pyrasis/golangbook/blob/master/Unit%2067/chat.go

    Visit original content creator repository https://github.com/kyopark2014/webchat-golang-socketio
  • DOML

    Data Oriented Markup Language – DOML

    By Braedon Wooding Latest Version 0.3.2

    No promises on breaking changes, I’ll try to keep compatibility however and most compilers will support you down grading your version or explicitly not allow it.

    Find the changelog or the formal specification document

    What is DOML?

    DOML is simple – it’s a markup language akin to JSON/YAML/XML/TOML/…/ with the usability of a language like LUA.

    A quick overview

    # Version 0.3
    // Construct a new Color
    Test = Color() {
      RGB = 255, 64, 128,
    }
    
    // Constructors do exist
    // the parameter names are purely for your own merit, they will check if its possible however (will be possible on most systems)
    TheSame = Color::Normalized(r: 1, g: 0.25, b: 0.5) {
      Name = "Bob"
    }
    
    // You can also just declare an object without scoping it
    Other = Color()
    Other.Name = "X"
    
    // You can declare random other values
    MyValue = 2
    
    // You can also edit the original Test at any point EITHER by doing
    Test.R = 50
    // Or by doing
    Test.{
      G = 128
    }
    
    // You can declare arrays like
    ArrayObject = []Color {
      ::Normalized(0.95, 0.55, 0.22){
        Name = "Other", // Trailing commas are always allowed
      },
      // You can still do an empty construction
      ::() {
        RGB = 50, 25, 125,
      },
      // And thus you can leave out the ::()
      {
        RGB = 50, 25, 125,
      },
    }
    
    // You can also copy objects by doing
    NewObj = Other
    
    // Or can do something like
    NewObj.Name = ArrayObject[0].Name
    
    // You can also declare arrays inside object definitions
    MyTags = Tags() {
      // Note: all have to be of the same type
      SetTags = ["Hello", "Other", "bits", "bobs", "kick"]
      Name = MyTags.GetTags[0] // And indexing them works like you would think
    }
    
    // You can declare dictionaries like
    // Dictionaries within objects can also be created similarly
    MyDictionary = [String : Color] {
      { 
        "Bob" : Color::Normalized(0.5, 1.2, 3.5) {
          Name = "Bob's Color"
        }
      },
    }
    // No need to keep classes around in this example
    # Deinit all

    When you put this into a parser you’ll get something like this; compilers are free to optimise by implementing quick calls and other methods, also almost all compilers suppport adding additional comments to each line to clearly demonstrate what each line does (for when you want to inspect the produced code). Furthermore the actual IR that you will use won’t be in simple mode (which is meant mainly for when you want to read/tweak it) since the excessive use of strings is inefficient.

    ; This is the resulting bytecode from the file given
    ; This bytecode will be overriden if new bytecode is generated.
    # IR simple {
      init 4 4 ; Initialises the stack and registers
      ; This is a comment
      ; Construct a new Color
      newobj #Test Color Color
      push int 255, 64, 128
      call #Test Color RGB
    
      push flt 1, 0.25, 0.5
      newobj #TheSame Color Normalized
      quickpush str "Bob"e
      quickcall #Test Color Name
    
      newobj Color Color #Other
      quickpush str "X"
      quickcall #Other Color Name
    
      quickpush int 50
      quickcall #Test Color R
    
      quickpush int 128
      quickcall #Test Color G
    
      push flt 0.95, 0.55, 0.22
      newobj #ArrayObject__0 Color Normalized
      quickpush str "Other"
      quickcall #ArrayObject__0 Color Name
    
      newobj #ArrayObject__1 Color Color
      push int 50, 25, 125
      call #ArrayObject__1 Color RGB
    
      newobj #ArrayObject__2 Color Color
      push int 50, 25, 125
      call #ArrayObject__2 Color RGB
    
      copyobj Color Color #NewObj
    
      quickget #ArrayObject__0 str Color Name
      quickcall #NewObj Color Name
    
      newobj Tags Tags #MyTags
      push vec str 5
      quickcpy vec str "Hello", "Other", "bits", "bobs", "kick"
      call #MyTags Tags SetTags
    
      get #MyTags Tags GetTags
      quickgetindex vec str 0
      pop 1 ; ^^ the array will get popped not ^^ as ^^ is a quick call and goes to a separate register.
      quickcall #MyTags Tags Name
    
      push flt 0.5 1.2 3.5
      newobj #MyDictionary__Bob 3 Color Normalized
      quickpush str "Bob's Color"
      quickcall #MyDictionary__Bob Color Name
    }

    Shortened Format

    Sometimes the problem with JSON is that it just bulks up so much and looks very noisy, so DOML provides a few ways to shorten your scripts;

    An initial doml script;

    Wizard : Character {
      Name = "Wizard the Great",
      Stats = {
        { Character.Stat.HP : 2 },
        { Character.Stat.AP : 9 },
        { Character.Stat.ST : 3 }
        // And so on
      },
      Spells = [
          Spell::Fireball(),
          Spell::New() {
            Name = "Polymorphism",
            EffectScript = "Polymorphism.lua"
          }
      ]
    }

    You could reduce this down to (using the idea of scoping variables)

    Wizard : Character {
      Name = "Wizard the Great",
      Stats : [Character.Stat : Int] = { HP : 4 }, { AP : 9 }, { ST : 3 }
      Spells : [Spell] = [Fireball(), New() { Name = "Polymorphism", EffectScript = "Polymorphism.Lua" }]
    }

    Types

    Type Example Values Details (all suffixes are case insensitive)
    Integer 12, -40, +2, 01010b, 0x40FF, 0o42310 0b for binary, 0x for hex, 0o for octal
    Double 10.5, 20, 5e+22, 1e6, -2.54E-2 E for exponent
    Decimals $40, +$99.05, -$4e+22 Can use E for exponent and ‘$’ refers to decimal
    String “This contains a ” escaped quote” “…”, you can escape " with \
    Boolean true, false The boolean values
    Object Test, X, MyColor Refers to a previously defined object

    Note: decimals have standidized for $ though many parsers will probably allow the various other currency signs.

    Collections

    Type Example Details (all suffixes are case insensitive)
    Arrays [1, 2, 3, 4] All have to be of the same type
    Dictionary { { “X” : 2 }, { “Y” : 9 } } All keys/values have to be same type (key != value)

    Actually using objects created

    There are a multitude of ways to use the objects i.e. actually give them to the application, often applications have some kind of ‘registerX’ function that registers the objects so I’ll follow that in this example.

    // First you could just do it on a base by base basis
    Wizard = Character {
      Name = "Wizard the Great",
      Stats : [Character.Stat : Int] = { HP : 4 }, { AP : 9 }, { ST : 3 }
      Spells : [Spell] = [Fireball(), New() { Name = "Polymorphism", EffectScript = "Polymorphism.Lua" }]
    }.Register();
    // Can also put it on its own line
    Wizard.Register();
    // Or do the identical call
    Character.Register(Wizard); // Presuming that it is a static method
    // Or do a localized call (calls Register on all characters)
    #LocalizedCall Character Register
    // Or just a mass call (calls Register on every object)
    #MassCall Register

    Serialization

    Compilers will support serialization, however they may just support it through a binary serialization (i.e. an outputted DOML IR file which isn’t text readable), all ‘official’ compilers will however support it in any format both binary, text readable and actual ‘DOML’ output.

    Comparison with other formats

    Hopefully the code examples clearly demonstrate DOML’s strengths, it is built for programmers as a de-serializable format to enable them to store data efficiently and effectively; it excels at being readable and simple (it’s grammar is extremely simple compared to any language out there), while it is similar to markup languages and similar to scripting languages I feel it sits somewhat in the middle, it is as useful as using LUA for your data management but as simple as JSON.

    Get Involved

    Anyways, if you have any new changes you may wish to add please ask in the issues! I will be more cautious to accept PRs if the changes aren’t talked about in an issue (though the obvious exception is if you are fixing up typos/errors or if its a super small thing, OR if you are adding your implementation / project to the list all these don’t require issues of course).

    Join the discord here; https://discord.gg/hWyGJVQ.

    Roadmap

    • V0.3.

    Projects using DOML

    • If you know of any please send a PR adding to this list!

    Version ‘Promises’

    • Each compiler will support each minor and major version but isn’t required to support each patch version.
      • Compilers can ignore this requirement for versions prior to v0.5 however.
    • At version 1.0.0, compilers are allowed for the only time to break compatability with previous versions as long as there is a stable ‘pre 1.0.0’ version (and hopefully maintain in terms of bugs for another year or two), this is to give the project a fresh slate and to prevent the slowdown from having to support multiple different versions.
    • Post v1.0.0 compilers have to just support each major version as before but as minor versions aren’t allowed to have breaking changes compilers aren’t required to support them (since all code written in vX.Y will work in vX.Z providing Z > Y).

    Implementations of DOML

    If you have an implementation, send a pull request adding to this list. Please note the version tag that your parser supports in your Readme.

    v0.3 Compatible Compilers

    • C#
      • Currently is about 3/4 complete.

    In Progress

    • C++
      • No progress has started (but it will start soon)
    • Go
      • Slightly v0.2 compatible but not v0.3 compatible yet.
    • Zig
      • Way too many compiler bugs in the way and the language is just not mature enough as it is changing too rapidly.

    Do you have a compiler in a language that you want to work on?

    • Go ahead! I won’t make any compiler ‘official’ (i.e. under the DOML-Lang ‘company’) till it is finished but it can definitely go on this list till then! I would like to have most of the compilers under the DOML-Lang banner as it gives them an air of officiality and we can ensure that they are supported for a while.

    Editor Support

    These will be missing a considerable amount of features as the language has recently changed, I’ll fix them up when I get time.

    • Notepad++ OUTDATED
    • VIM OUTDATED
    • VS-Code
    • EMACS/Sublime Text/… are all in development (and will be released soonish)
    Visit original content creator repository https://github.com/DOML-Lang/DOML
  • OneTwoThree

    One Two Three

    A social network app allowing to find a dancing buddy.

    Have you ever wanted to go to a dancing class, but were too shy to go alone? OneTwoThree is a social network, enabling you to look for a buddy or a group of buddies to join a certain class with you.

    Final group project of Le Wagon Web Development Bootcamp. Batch #601

    The idea behind the project was to create a mini social network app, where people can organise themself around different dancing event places and classes and find dancing partner or entire group. Another layer of the application was a gamification aspect with achievements system and levels depending on number of lessons completed and feedback from dancing partners.

    Our team joyfully spent about half of the time given to produce the application on planning, designing on paper, Whimsical, Figma and sketching countless iterations of the schema. 🤨

    As a result of the challenging second half, we came up with the product presented here that can be visited below.

    Enjoy!

    The application is deployed to Heroku and available here:

    Main Page

    Getting Started

    Setup

    Install gems

    bundle install
    

    Install JS packages

    yarn install
    

    ENV Variables

    Create .env file

    touch .env
    

    Inside .env, set these variables.

    CLOUDINARY_URL=your_own_cloudinary_url_key
    MAPBOX_API_KEY=your_own_mapbox_url_key
    

    DB Setup

    rails db:create
    rails db:migrate
    rails db:seed
    

    Run a server

    rails s
    

    Password: testing


    Dev log

    Built With

    Languages and Tools:

    ruby rails postgresql javascript html5 css3 bootstrap git heroku figma linux photoshop


    Design process using whimsical

    Available at: Whimsical/OneTwoThree


    UX/UI using Figma

    Available at: Figma/OneTwoThree

    Figma


    Schema of the application changed a lot and went through many iterations

    The final schema of the application:

    Schema

    And some of the older versions:


    Back End

    Application consist of eight models in total! -User – Entire User logic was created using DEVISE – Authentication logic – Photo attachment using Cloudinary as active_storage – After logging in User can either look for other users to dance with or look for places to dance.

    • Place
      • Photo attachment using Cloudinary as active_storage
      • Phisical object, schools of dance, music clubs with occuring dancing events
    • Event
      • Photo attachment using Cloudinary as active_storage
      • Is taking place in “The Place” (duh!)
      • Created by User, owner of the Place
      • May have many attendants, groups and invites
    • Invite
      • User can either add yourself to the even, invite someone else straight to the event or create a grou or add someone an existing group of people going together to the given event.
      • Each user story have differen routes and path and its carrying different sets of params throughout all views. Not challenging at all. Not even a bit…
    • Group
      • Backbone of the aplication
      • Internal dashboard for group of people going together to that one given event in that one place.
      • Fully dynamic with responsive menu allowing to add participants and with build in chat created using WebSocket and ActionCable
    • Review
      • After participating with some other user in an event or after beeing with him in a group you can leave a “review” at his profile pic that only you will be able to modify, a part of gamification aspect of the application, depending on rating of those reviews each user will progress with level and get a new achievement.
    • Chatroom
      • Part of the live chat logic in Group model
    • Message
      • Look above!

    Extra features

    • Entire User logic with authentication done with DEVISE
    • Geolocation for Users and Places done with Mapbox
    • Search Engine through Users or Places done with pg_search
    • Photo attachment using Cloudinary as active_storage for Users, Places and Events
    • AJAX for Reviews
    • Webpack and Action Cable for Live Chat in Groups

    Front End

    There are some aspects of front end I’d like to mention

    Animated Background

    Animated background of the application is done purely with use of CSS and this is something I’m the most proud of. It consists of a div with gradient moving basically left to right and top to bottom. Inside the div, there is an empty list that serves as those animated squares in the background.

    <div class="gradient"></div>
    <ul class="circles">
      <li></li>
      <li></li>
      <li></li>
      <li></li>
      <li></li>
      <li></li>
      <li></li>
      <li></li>
      <li></li>
      <li></li>
    </ul>
    

    While gradient is just translating its position in two axis, list elements are moving vertically, rotating and decreasing opacity at the same time in a loop.

    .gradient {
      z-index: -10;
      position: fixed;
      width: 100%;
      height: 100%;
      background: linear-gradient(-45deg, #8741e6, #b2519f, #da5e58, #d8b46e);
      background-size: 400% 400%;
      animation: my-gradient 10s ease infinite;
      overflow: hidden;
    }
    
    @keyframes my-gradient {
      0% {
        background-position: 0% 50%;
      }
      50% {
        background-position: 100% 50%;
      }
      100% {
        background-position: 0% 50%;
      }
    }
    
    .circles{
      padding: 0;
      margin: 0;
      z-index: -9;
      position: fixed;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      overflow: hidden;
    }
    
    .circles li{
      position: absolute;
      display: block;
      list-style: none;
      width: 40vw;
      height: 40vh;
      background: rgba(255, 255, 255, 0.2);
      animation: animate 25s linear infinite;
      bottom: -150px;
      
    }
    
    .circles li:nth-child(1){
      left: 25%;
      width: 80px;
      height: 80px;
      animation-delay: 0s;
    }
    

    Responsiveness

    What’s worth mentioning is the almost full responsiveness of the entire app. It could use some final touches, but overall I’d like to present examples below:

    Conclusion

    Le Wagon Coding Bootcamp was simply the most amazing learning experience in my life with teaching quality I’ve never seen before and that application is the final showdown of all the skills acquired during the bootcamp. There is still so much to do, but it’s mostly refactoring and working on the front end. The only important bit that is really missing is Testing and any TDD, CI/CD principles, but realistically, considering the time given – that was a necessary sacrifice. Considering that this application is shared effort, despite all those missing elements I think it is a viable product and it suffices to leave it in that state.

    Acknowledgements

    Big thank you to the most amazing team ever!

    Michale Barrett For all your work on the hardest bits with JS and best Seed file I’ve ever seen! 👍

    Ervis Lapi For the initial idea and giving your heart and soul into this app. 🤍

    Once again – sorry guys for hijacking Front End of the App. I promise it’s the last time! 😄

    License

    This project is licensed under the MIT License.

    Visit original content creator repository https://github.com/Jacek-Jan-Nowak/OneTwoThree