Giter Club home page Giter Club logo

heborn's People

Contributors

chrisfls avatar pedrohlc avatar renatomassaro avatar themaxhero avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

heborn's Issues

index.html should not be cached

We can heavily cache both app-[hash].{js,css}, but index.html should always be fetched from origin, so it returns a new hash in case app.js/css has changed. Index.html is quite small anyway, it represents less than 1% of the total page size.

Not sure if it's being cached by nginx or cloudflare or both.

Right click is misplaced on windows

Steps to replicate:

Right click on any window (with context menu support). The context menu will be far from the mouse. That's likely an css issue (on the landing page, if you right click on the sign-up component, it will work correctly). Another example of right click working correctly is this demo.

Proposal: change expose/import name conventions

We're currently using a import/expose convention that looks like that:

module OS.Messages exposing (OSMsg(..))

import OS.WindowManager.Messages

type OSMsg
    = MsgWM OS.WindowManager.Messages.WMMsg

I propose changing it into that:

module OS.Messages exposing (Msg(..))

import OS.WindowManager.Messages as WM

type Msg
    = WMMsg WM.Msg

Why?

*.Messages, *.Models, *.Subscriptions, *.Update and *.View are parts of the same *, I believe that they were split to make things easier on eyes and to reduce compiler stress when changing minor things, so it may make some sense to join them when accessing from the outside.

Elm allows importing multiple modules under the same alias, and it will trigger warnings on name collisions, but this is not even a problem because:

  • Messages just exposes Msg types;
  • Subscriptions just exposes one function;
  • Update just exposes one function;
  • View may expose many functions, but usually just view, additional functions could get a "view" prefix to avoid collisions;
  • Models expose many types and functions, but they should not collide with the previous modules unless we do something really bad;

Another thing is that this change reduces some cognitive load.

Websocket disconnect problem

A recent PR (PR #131) changed how login and logout works (to make the UI less optimistic), the changes were:

  • The game just logs in after socket connection
  • The game logs out after socket disconnection

But it looks like that the production connection is too unstable, so the game logs out after 10 seconds of connection.

I'll try to make it more fault tolerant but I really believe that the connection is too unstable, this should be further investigated.

(this problem couldn't be tested locally, local websocket connections are too stable)

(edit: turns out that this is a balancer misconfiguration)

No feasible way to call Apps.update after changing GameModel [...]

No feasible way to call Apps.update after changing GameModel or...

Discussion: How Game should affect Apps


I've found a problem while designing/planning the models of the DesktopManager (aka Workspaces), I'll try to be as didactic as possible now...

As of #103, we forbid Game -> App communication, right? Tons of advantages, simplifies things a lot and etc but...


There's no way to reliably update an App model after updating the Game model.



<assumptions>
Ideally, we want to update our Apps model after changing the Game model.
</assumptions>


To make this happen, we have to do this flux:

    every GameModel.update
    calls Apps.update

It's not possible to do this flow right now for two main reasons:

  1. There's no way to create a global message GameUpdate and pass it forward to the Apps, so using message based solutions requires adding tons of boilerplate. 😞
  2. There's no App function to sync apps with the GameModel.

There is three main solutions for that:

  1. Adding a GameUpdateMsg to each App model.
    • PROS: No need to add another function to manage Game model.
    • CONS: Extra message boilerplate for every App (and also OS).

  1. Adding an extra function that receives the GameModel without any message.
    • PROS: A lot less boilerplate on fathers.
    • CONS: One more API function, more boilerplate on Apps.

  1. Forbid any App model update based on GameModel, removing GameModel param from Apps update function
    • PROS: No extra boilerplate, Apps will just contain UI state. (separation of concerns)
    • CONS: Opinionated (technically this could be actually a pro), less flexibility, may (or not) require moving more state to Game.

Obviously I'm a fan of the 3rd solution 😄 , but it might be the wrong solution for us, it's too much opinionated. (actually the 3rd solution introduces heavy overhead unless we use an app cache system within Game, so I'm not liking this solution anymore)

Note: Maybe this whole issue is no surprise, maybe we don't want to keep any state references to
anything on GameModel, but these are just assumptions, I'm not sure of anything.


The most important to think is: What we decide now will change how we design every App models.



NOTE: Everyone is assigned for discussion, but I'll be the one who will fix it

Reach Code Consistency

I just opened this PR to track existing code consistency problems.

The current main problems are:

  • passed down params (& order) for TEA functions (dispatcher and minor refactors fixed that)
  • param ordering (it should be "data last") #88 (almost done 😄 )
  • import/export #109

Fuzzing found a bug

Funny this happened after 5 or 6 long builds, so probably passed some 600 tests until it found this one 😲

[Test] Running 39 tests. To reproduce these results, run: elm-test --seed 486670792
[Test]
[Test] ��� heborn
[Test] ��� filesystem
[Test] ��� file operations
[Test] ��� delete files
[Test] ��� delete folder
[Test] ��� folder path no longer exists
[Test]
[Test] Given 1389533003
[Test]
[Test] True
[Test] ���
[Test] ��� Expect.equal
[Test] ���
[Test] False

from this build

Unable to login

On the main 1.hackerexperience.com portal the login button no longer does anything

Server SessionManager (internally known as Workspaces)

SessionManager

previous session manager draft


While designing our `WindowManager`, we got some problems:
  • What happens with windows when an user switches from one endpoint to another?
  • How to allow an user to switch between owned and invaded servers without confusion?

These problems gave birth to one pretty powerful feature: session management (aka workspaces / virtual desktops).

But they won't work like everyday virtual desktops, cause they're not virtual desktops of a single computer, but of many.



UX Facts

  • An App Window allows you to control a Server;
  • There are multiple owned Servers running at same time;
  • Gateway and Endpoint are window contexts;
  • You always have a Gateway, that represents your owned Server;
  • Sometimes you have an Endpoint, that represents the server you're invading;
  • So... Gateway windows allows you to control your servers, Endpoint windows allows you to control invaded servers. (there are some windows without context, those won't allow endpoint controlling).

UX Problems

Our requirements are easy to understand, but hard to implement with simple solutions:

  • We want users to easily change between their owned servers and invading servers;
  • What we'll do with their windows after they change their context?

Bad Solutions

There are some solutions already discussed, but they are confusing:

  • Rename Gateway and Endpoint to IP/aliases
    • Toggling the Context is confusing
    • Desktop gets bloated easily

  • Deleting every Window with invalid state
    • Unexpected effect
    • Showing a confirmation modal is gameplay disruptive

The "Not so bad solution"

While this is not the best solution, it's the one that works with our current backend:

  • Marking the window content as Unreachable window content until state gets valid again.

Weird behavior when opening new windows

Looks like that opening multiple windows moves them around.

How to reproduce it:

On a newly opened tab:

  • Open a new LogViewer window
  • Type something on the filter field
  • Open another LogViewer window
  • The newly opened window will contain the filter of the previous one

Apps subscriptions are broken

This is a side-effect of #107. Solving it is required before solving this one.
Before 1b4806b, Core used to subscribe all apps using a MsgApp. Now, apps subscriptions are waiting their own model and their subscriptions are broken.
FYI: The only subscription we are using in apps right now is the one which propagates ContextMenu events (like closing it).

Yet unplayable features

I would like to start by saying that I was able to successfully migrate and login to HEBorn. It has a very good design. But there are some bugs:

  1. You do not have the ability to edit your logs.
  2. Browser comes up blank.
  3. You do not have the ability to edit your files in any way.
  4. Yes I know it is very early in the Alpha.

Initial Browser and DNS experience

What we already have:

  • DNS result decoded to Okay
  • VPC/NPC differing
  • Browser's Tabs have Id
  • Loading page (UnknownModel)
  • Pages can have their own models
  • Start cracker process (dispatch brute-force request)

Tasks :

  • add to DNS request
{ browser: WindowId, tab: Int }
  • add this to response
  • parse 404 result
  • get rid of Game.Web.*
  • adapt browser for requesting pages
  • adapt browser for loading
  • dispatch result to browser
  • adapt browser for receiving pages
  • parse metadata
    • psw placeholder
      • adapt page browser model and dns metadata to handle this
  • parse more hackables npcs
  • parse their metadatas too
  • Rename type Browser to Tab
  • Add spinning icon to Loading page
    • Loading pages can't be on history
    • Can only insert fetched page when on loading && url matches
  • Remove dummies
  • Apps.Browser.Pages.Default.View add onClick to Crack btn
  • Use Endpoint.member in A.B.Pages.Default.View to hide password field

Rename `Context` to `Menu`

With the addition of Context (local or remote) with #52, we need to replace all previous Context entries with Menu to make sure it does not get confusing.

Refactor our messages to not allow functions on them

While adding new channels/ws requests, it got to my attention that we're breaking some core rules of the elm:

One of the core rules of The Elm Architecture is never put functions in your Model or Msg types.
It may cost a little bit of extra code to model everything as data, but the architecture and debugging
benefits are worth it. - evancz

We're breaking this rule by allowing ResponseDecoders on our Core.Msg type.

While it doesn't do anything too bad right now (aside from blocking the export/import history feature of the time travelling debugger), it will make our life harder in the near future as elm doesn't stringfy functions, making it impossible to inspect their content properly while debugging Msgs.

Also, I believe that there's plenty room for reducing boilerplate from our codebase (or at least better organizing for scale... Requests.Models I'm looking at you).

EDIT: another problem found, we're using messages as commands on both Core & Requests

Crash vs Maybe for invalid responses

I'm introducing Maybe Response to avoid having tons of NoOps types over the code.

Before doing that we were using a Debug.crash to cast Result a b to b, to avoid having to deal with Results/Maybes on */Update.elm...

This had a good reason on that time, but now (with the new structure for Updates) the cost of handling maybes is fairly low.

The advantages of crashing are that it's impossible to play the game with an outdated client, but crashing is makes the game unresponsible. It would be better to introduce a "blocking modal" asking the player to refresh the window.

I'm proposing to replace the Debug.crash with a Result.toMaybe-like function (that will still report errors without crashing).


@renatomassaro @PedroHLC

Implement Window minimize behavior

Minimize window works similarly to maximize, with the difference that we may have to render multiple minimized windows while only one maximized window can be rendered at a time.

This is how I see window minimize working:

1 - Player clicks on minimize button from an open window, it goes to the icon dock.
2 - On the icon dock, every minimized window is displayed as a dot (or light) below its application icon. Similar to mac os.
3 - Once the player clicks on the icon (with minimized window), the window becomes visible again at the position it was before.

It's all easy and stuff, but here are some edge cases that makes this trickier:

  • What if player wants to open a new window alongside the current one?
  • If there are two (or more) minimized windows of the same type, how to show it? How to select which one to "open"?

My opinion on this ( @mememori happy to hear yours too):

  • The dot on the icon dock indicates there are open (minimized or not) windows from that application.
  • If the player clicks on the Application icon and there's no open window, it will automatically open the first one.
  • If the player clicks on the application icon and there are open windows, but not minimized ones, it will open a new one automatically.
  • If the player clicks on the application icon and there's one or more minimized windows, it will display a "drop-up" with the options [Open new window | <title from minimized window> ]. This is similar to Unity (which we all hate).

Recreate notifications

What we already have:

  • an almost-useless OS.Header.Notifications

Tasks:

  • Create model
    Dict Id { content: Union, action: Union, time: Time, read: Bool }

    • filterUnreaded
    • countUnreaded
    • hasUnreaded
    • read id
    • getOrdered
    • metadata on content
    • optimistic
    • Choose namespace to place
  • Apply this type to:

    • Game.Servers.Models.Server.notifications
    • Game.Account.Models.Model.notifications
    • Game.Chat.Models.Model.notifications
  • Discard OS.Header.Notifications

  • Adapt OS.Header.View

    • Create account gear
    • Separate per chat, servers, account gear
    • Add counted bubble
    • Add per endpoints bubble
  • Create toast viewing as OS.Toast

    • Model
      { toShow : (id: NotificationId, until: Time) }
    • View
      • onHover mark read
      • opacity/display with until
      • add to OS
    • Style
    • Updates
      • Insert
      • Clean olders when inserting
  • Notifications bootstrap

    • Discuss format with backend
  • Notifications .Updates

    • Servers
    • Account
    • Chat
    • Dispatch new toast
  • New notification event

    • Response format
      • Discuss format with backend
    • Decoders

Update API to have iteratee first and data last

Files that need to change:

  • src/Apps/Explorer/Models.elm

    • setPath
    • getPath
  • src/Apps/LogViewer/Models.elm

    • isEntryExpanded
    • toggleExpanded
    • applyFilter
    • updateEditing
    • toggleExpand
    • leaveEditing
    • getEdit
    • updateTextFilter
  • src/Game/Account/Models.elm

  • src/Game/Servers/Models.elm

  • src/OS/WindowManager/Models.elm


This issue is mostly deferred until #84 is merged.

[EPIC] - Log Viewer

  • #40 UI mockup
  • #41 Make Game.Log models at par with backend
  • #42 Add support for common log operations
  • #43 Implement design of Log Viewer
  • #44 Add game mechanics behaviors to Log Viewer

[EPIC] - Continuous Delivery for HEBorn

Description

Build, test and release automatically. Improves overall project quality and confidence, as well as enabling us to iterate quickly. CD makes a dozen of releases per day become boring.

Tasks

  • Prepare build server
  • Prepare prod server
  • Automate release with a Jenkinsfile

Extra pixel on window header

The separation between the window header and the window body contains one extra pixel that makes the blue background visible in a very thin line between the header and the body. Do you see it?

[EPIC] - File Explorer

  • #34 UI mockups
  • #35 Make Game.Software models at par with backend
  • #36 Add support for common file operations
  • #37 Implement design of File Explorer
  • #38 Add game mechanics behaviors to File Explorer

Abstract View render logic

So, here's an idea to make our dev flow easier.

Currently each object from the View, like any log entry or file entry, is hard-coded into the view itself. Try to abstract the act of loading the object from rendering (styling) it.

Example:

Instead of

            [ div [ class [ CntListEntry, EntryDir ] ]
                [ span [ class [ DirIcon ] ] []
                , span [] [ text "Downloads" ]
                ]
            , div [ class [ CntListEntry, EntryArchive ] ]
                [ span [ class [ VirusIcon ] ] []
                , span [] [ text "MyVirus.spam" ]
                , span [] [ text "2.3" ]
                , span [] [ text "230 MB" ]
                ]
            , div [ class [ CntListContainer ] ]
                [ div [ class [ CntListEntry, EntryArchive ] ]
                    [ span [ class [ FirewallIcon ] ] []
                    , span [] [ text "TheWall.fwl" ]
                    , span [] [ text "4.0" ]
                    , span [] [ text "230 MB" ]
                    ]
                , div [ class [ CntListChilds ] ]
                    [ div []
                        [ span [ class [ ActiveIcon ] ] []
                        , span [] [ text "Active" ]
                        , span [] [ text "4.5" ]
                        , span [] []
                        ]
                    , div []
                        [ span [ class [ PassiveIcon ] ] []
                        , span [] [ text "Passive" ]
                        , span [] [ text "3.5" ]
                        , span [] []
                        ]
                    ]
                ]
            ]

use something like

loadFiles model =
    -- files = (getFilesOnPath model)
    files = [file1, file2, file3]
    List.map renderFile files

renderFile file =
    div [ class [ CntListEntry, EntryArchive ] ]
        [ span [ class [ file.icon ] ]
        , span [] [ text file.name ]
    ]


viewExplorerMain model =
    renderHeader model
    renderEntries model

renderEntries model =
    div [ class [ ContentList ] ]
         [ loadFiles ]
l

Above code is wrong, but it's OK to get an idea of what I mean. In simpler words, make the View code generic.

The List.map renderFiles files is just a suggestion, you don't have to do exactly like this. Though it seems like the way to go. Probably the best way to get files on path is to use Filesystem's function getFilesOnPath.

By default your filesystem is empty, so if you want to add some dummy data, all you have to do is replace the original files list with myMadeupFiles or something like that.

I'm open to suggestions on how to improve this "pattern".

Optmize Jenkins

Hello @renatomassaro.

Today, each Jenkins builds took almost 3m and 40s to finish. Sometimes we have to merge more than one PR ready to merge, and because of jenkins after merging one we have to wait before merging the next.

I think we can improve Jenkins in two-ways:

  1. Cache npm-modules
    It takes too much time to install modules, and it sometimes it randomly fails.
    We could use a solution like this: Speeding Up NPM Installs, saving our tar in $JENKINS_HOME
    (We should also cache, in a separate tar, our submodules...)

  2. Change ('Lint', 'Test', 'Compile') from parallel to serial tasks
    We all know how painful is to run multiple instances of elm simultaneously. Poor jenkins farm...
    Lint and tests fails much earlier than compiling would. This would reduce resources usage.

:: OFF-TOPIC:: Is jenkins building PRs for any github member? Can one add a PR with a modified Makefile that will run crazy shell commands?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.