#dev-general

1 messages ยท Page 72 of 1

distant sun
#

Hf with that api I guess.

pale shell
#

thanks i think i sorted it lol

obtuse gale
#

@heady birch whats something like a UserRepository in spring?

#

So, this is how I understnad it, idk if its right,
1 - The controller decides what happens when you go to the url
2 - The UserDto like puts it on the database?(Not certain about that one)

#

idk if thats right lol

frigid badge
#

@obtuse gale read up on the repository pattern.

obtuse gale
#

where abouts would i do that?

heady birch
#

UserRepository puts it in the database

#

deletes stuff and finds stuff

#

UserDto represents the html <form>

obtuse gale
#

Alright, so like do i have like a UserDto class, and a User class?

#

or just one

heady birch
#

yeah 2

obtuse gale
#

and like whats the difference

heady birch
#

User represents a user in the database

#

UserRepository handles getting User and putting a User in the database

#

UserDto will be used by the controller and your service

#

Service will check that UserDto password matches e.g
Edit: or form validation

#

And Service will create a new User based on the details of the UserDto

#

And Tell UserRepository.save(User)

obtuse gale
#

ah

#

what are some like standard package names? Idk what to call packages for these kinda things lol

heady birch
#

some peopl group like

#

repository controller service config dto

#

I usually do it like this

#

user - would have UserRepository User UserDto e.g

obtuse gale
#

ah alright

night dagger
#

some can help me?

#

im trying to create /kits gui menu which can provide player kits in click on gui item

#

i can do it with deluxemenus?

obtuse gale
#

What does adding an attribute to a model do niall? I keep making the mistake of just typing stuff out without knowing what it does

hot hull
#

How do I clone from gh from a certain commit?

distant sun
obtuse gale
#

Hello, is there someone who could give me a โ€žsimpleโ€œ plugin? i define simple as, made in IntelliJ, nothing special like a shorter version of worldedit or a better version of essentials

lunar cypress
#

what for

hot hull
#

How is that "simple" kek

obtuse gale
#

i dunno

lunar cypress
#

there are lots of open source plugins out there

obtuse gale
#

where ๐Ÿ˜„

heady birch
#

What does adding an attribute to a model do niall? I keep making the mistake of just typing stuff out without knowing what it does
@obtuse gale It makes it accessible to Thymeleaf

#

So if I have object:

#
class Car {
  var name: String
  var manufacturer: Manufacturer
}

class Manufacturer {
  var name: String
}

model.addAtribute("car", Car())
pale shell
#

Why are vectors so annoying, I'm just trying to minus vec1 from vec2 and i have a 139MB error log lol

heady birch
#

Car Name: <span th:text="${car.name}"></span>
Car Manufacturer: <span th:text="${car.manufacturer.name}"></span>
hot hull
#

Gaby, I'm so confused lmao

heady birch
#

I love kotlin

#

@topaz bay Thank you, I also have a question

#

Obviously companion object is useful for putting static variables

obtuse gale
#

ahh

#

I see

heady birch
#

It looks as if theres no equivalent to the static block however

static {
//..
}```
topaz bay
#

init

obtuse gale
#

niall what would go in the User class? not the UserDTO class, just the USer class

topaz bay
#
companion object
{
  init 
  {
    // code here
  }
}
heady birch
#

@obtuse gale The coloumns in the database

#

id, username, password, email

obtuse gale
#

huh

#

do i need to annotate it fancily?

heady birch
#

Yeah

obtuse gale
#

what would that look like

heady birch
#

Of course you only really want what you need in the database

#

Maybe start with just id, email, username, password

distant sun
#

@topaz bay that's wrong

#
companion object {
  init {
    // code here
  }
}```
obtuse gale
#

yea, so how come like id and password have @Column, but email doesnt

#

And whats manytomany and jointable

topaz bay
#

@distant sun Your existence is wrong.

heady birch
#

Those are relations

#

When you start to get more than one table

distant sun
#

@topaz bay WRONG

topaz bay
heady birch
#

You can if you want annotate them all with Column

hot hull
#

Sx knows what's up lmao

heady birch
#

They are only doing it to specify specific things (like the length, or wether the column has to be unique)

#

So they should really have

obtuse gale
#

wdym unique?

heady birch
#
@Column(unique = true)
private String email;
prisma wave
#

the column contents has to be unique

heady birch
#

unique as in no two User can have the same email address

obtuse gale
#

ah

heady birch
#

I think I followed this tutorial and some users would spam the register button and end up with 3 accounts

obtuse gale
#

ah

#

Do I need to like

#

setup the table

frigid badge
#

migrations

heady birch
#

No the only thing you need to make sure exists is the database

#

And it creates the tables automatically from your User class

frigid badge
#

orms are pretty neat rarely use them in java though tbh

#

not that I actually do lots of java anyway

heady birch
#

Yeah they are very good

nocturne dock
#

Hey there! I have now finished learning quite a bit about java and I would now like to move on to minecraft plugin development. What is a good place to start learning + should I use craftbukkit or spigot?

lunar cypress
#

depends on your use case

#

If you wanna do big, maybe commercial plugins, there's probably no way around spigot

#

The wiki is a good place to start

nocturne dock
#

Is spigot better the bukkit?

pale shell
#

@nocturne dock should be ye

nocturne dock
#

What is the difference?

lunar cypress
#

spigot is somewhat of the continuation of bukkit

obtuse gale
#

user paper tho lol

lunar cypress
#

It uses bukkit as its base and was originally a separate fork, but now bukkit is abandoned afaik

obtuse gale
#

Niall, I see in the github thingy u linked it had

#

private Collection<Role> roles;

#

I get the following if i do that

#

'Basic' attribute type should not be a container

nocturne dock
#

okay! Is there some good way of learning everything in Spigot without just browsing the forums?

prisma wave
#

javadocs are always handy

#

@obtuse gale you will need @ElementCollection or @OneToMany I believe

lunar cypress
#

although spigot's are pretty shit

distant sun
#

^

obtuse gale
#

Hm, what do those do though?

nocturne dock
#

What is paper?

prisma wave
#

@OneToMany makes a relationship - one user will have many roles for example

#

A fork of spigot

nocturne dock
#

Is paper better then spigot?

prisma wave
#

Yes

obtuse gale
#

ah

nocturne dock
#

Should I learn that?

prisma wave
#

the API isn't very different

#

if you know one you pretty much know all of the other

#

Paper mostly improves things under the hood

nocturne dock
#

so I can just start with spigot

prisma wave
#

yep

nocturne dock
#

oke

obtuse gale
#

'One To Many' attribute value type should not be 'Role'

prisma wave
#

Is Role an @Entity?

obtuse gale
#

o do i need to make a role class

#

i just imported one

#

no clue hwere from

prisma wave
#

oh

#

Well relationships are between entities so

#

you also probably want a bidirectional relationship, so if Role has anything referencing a User or whatever it is, give that @ManyToOne

obtuse gale
#

hm

#

see this many to one and many to many stuff is the bit that confuses me lol

#

What does it effect in the database?

prisma wave
#

It's confusing at first

#

this is why diagrams and things exist

#

Basically it makes foreign keys to map to the other entity

obtuse gale
#

wat

prisma wave
#

Basically

#

It will store the Id of the other entity

topaz bay
#

I would imagine if you actually know sql it would make sense

obtuse gale
#

lol

prisma wave
#

So something like:
users:
| Id | Name | Age |
| 1 | Dave | 39 |

Will also have
user_roles:
| User_id | role_id |
| 1 (Dave) | 1 (Admin) |

#

There would also be a Roles table but I'm on mobile and last

#

Lazy*

obtuse gale
#

er

#

i kidna get it

#

So do i need to like make a custom role class and stuff?

prisma wave
#

possibly

#

Isn't Role part of the Java security API or something?

obtuse gale
#

ive currently got it imported from
package java.util;

#

wait

#

no i dont lol

#

javax.management.relation

#

But with @OneToMany i get One To Many' attribute value type should not be 'Role

heady birch
#

You need your own Role class

#

And wouldnt it be ManyToMany

obtuse gale
#

No clue

#

what would the role class contain?

prisma wave
#

oh yeah ManyToMany mb

heady birch
#

Integer id,
String name

pretty much

obtuse gale
#

ah ok, and how do roles work? Like is it so i can have an admin only page and stuff?

heady birch
#

Basically yeah

obtuse gale
#

I still get the same thign

heady birch
#

Have you made sure your importing your Role class

#

and your Role class is anottated with @Entity

obtuse gale
#

ah

#

that was it

#

forogt @entity

#

in the guide they use java private static List<GrantedAuthority> getAuthorities(List<String> roles){ List<GrantedAuthority> authorities = new ArrayList<>(); for(String role : roles){ authorities.add(new SimpleGrantedAuthority(role)); } return authorities; }

#

That takes in a list of strings, and they use user.getRoles, for me user.getroles returns a collection of roles

#

I could adjust it to this maybe

#
    private static List<GrantedAuthority> getAuthorities(Collection<Role> roles){
        List<GrantedAuthority> authorities = new ArrayList<>();
        for(Role role : roles){
            authorities.add(new SimpleGrantedAuthority(role.getName()));
        }
        return authorities;
    }```
heady birch
#

Yep thats correct

obtuse gale
#

alright

#

do i need to do anything in my application.propeties?

distant sun
#

so tempted to throw a stream there ๐Ÿ˜ฎ
roles.stream().map(role -> new SimpleGrantedAuthority(role.getName())).collect(Collectors.toList())

heady birch
#

Anything else.. or have you already got stuff in there?

obtuse gale
#

nothing atm

heady birch
#

Are you using mysql?

obtuse gale
#

I think s olol

heady birch
#
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect

spring.datasource.url=jdbc:mysql://HOSTNAME:3306/DATABASENAME?useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
spring.datasource.username=USERNAME
spring.datasource.password=PASSWORD```
#

Make sure you do it on empty database

#

You might not need line 2 really.. but I had some issue and that fixed it

obtuse gale
#

yea, do i need to run something like xxamp in the background or whatever? Or is the database hosted like with intellij

heady birch
#

You will need to host it

obtuse gale
#

alrgiht

heady birch
#

So yeah xammp would work

obtuse gale
#

Does like spring have some sort of default login thing? I found it on google yesterday when i was looking up registration form... now ive started my app, im like stuck at this login page that i didnt make lol

prisma wave
#

yeah spring security makes one by default

obtuse gale
#

yea lol how tf do i get rid of it lol

#

I think i got rid of it

#

But now i always get

#

welp i got it to somewhat work

#

I got the form to show up, but when i click submit the page just refreshes and i go to a page that says tjhe error type is Forbidden

heady birch
#

Yeah so you should have an error come up in the run window in IDEA

obtuse gale
#

er

#

nope

heady birch
#

Oh not found

#

hm

#

Whats the address in the URL bar

obtuse gale
#

na, that errors old, now when i complete the form it takes me to localhost:8080 and gives this

heady birch
#

What is the location of form

#

like /register?

obtuse gale
#

/user/register

heady birch
#

ok

#

Could you send your template for /user/register? (html file)

#

Most likely your form doesnt submit to correct location

#

Or you need @PostMapping instead of @GetMapping when processing form

obtuse gale
#

=paste

compact perchBOT
#
HelpChat Paste

Please use a paste service to share configs, errors, code and long logs.
โ€ข HelpChat Paste

obtuse gale
heady birch
#

replace action with

#

th:action="@{/user/register}"

obtuse gale
#

alrgiht

heady birch
#

Can you send the controller class?

obtuse gale
#

oh wait no thats my bad, my things action registration

heady birch
#

Validation failed

#

So thats to do with your UserDto class

obtuse gale
#

ah

#

it was cos my passwords didnt match

heady birch
#

Ok so now you will definatley get an error in the console

#

look carefully for the useful part

#

If you cant find it paste it here

obtuse gale
#

ah an npe

#
    at com.aj.website.service.UserService.emailExists(UserService.java:27) ~[classes/:na]
    at com.aj.website.service.UserService.registerNewUserAccount(UserService.java:18) ~[classes/:na]
    at com.aj.website.controller.RegistrationController.registerUserAccount(RegistrationController.java:37) ~[classes/:na]```
heady birch
#

whats in UserService:27

obtuse gale
#

return userRepository.getUserByEmail(email) != null;

heady birch
#

is your userRepository autowired?

obtuse gale
#
    @Autowired
    private UserRepository userRepository;```
#

ye

heady birch
#

where does email come from

#

I mean what you pass to that function

obtuse gale
#

userDto.getEmail())

#
    @Transactional
    @Override
    public User registerNewUserAccount(UserDto userDto) throws UserAlreadyExistsException {
        if(emailExists(userDto.getEmail())) throw new UserAlreadyExistsException("There is already a valid user with the email: " + userDto.getEmail());
        User user = new User();
        user.setFirstName(userDto.getFirstName());
        user.setUsername(userDto.getUsername());
        user.setEmail(userDto.getEmail());
        user.setPassword(userDto.getPassword());
        return userRepository.save(user);
    }
    private boolean emailExists(String email){
        return userRepository.getUserByEmail(email) != null;
    }
}
heady birch
#

Let's see UserDto

obtuse gale
heady birch
#

Thats odd

#

UserDto could be null?

#

I assume you have in one of your controller methods:

#

@Valid UserDto user

obtuse gale
#

public ModelAndView registerUserAccount(@ModelAttribute("user") @Valid UserDto userDto, HttpServletRequest request, Errors errors, ModelAndView mav){

heady birch
#

yeah looks right

obtuse gale
#

hm

#

er

#

any idsea?

heady birch
#

No

#

other than try printing some stuff just to find out whats null

obtuse gale
#

alright

#

bruh im lost lol

#

email isnt null, so like what could it be, since thats where the NPE is from

#

return userRepository.getUserByEmail(email) != null; thats the excact line thats giving it :/

heady birch
#

Maybe try replace method="POST" with th:method="POST"

obtuse gale
#

how do u reset ezprestige data xD?

heady birch
#

public ModelAndView registerUserAccount(@ModelAttribute("user") @Valid UserDto userDto, HttpServletRequest request, Errors errors, ModelAndView mav){

#

And this method is annotated with @PostMapping?

obtuse gale
#

ye

heady birch
#

Ok

obtuse gale
#

how do u reset ezprestige data xD?

#

@PostMapping("/user/registration")

oak coyote
#

it will be as simple are removing the data files it creates @obtuse gale

#

i don't see how that's difficult

obtuse gale
#

theres none though

oak coyote
#

there has to be

obtuse gale
#

only config & prestiges.yml

oak coyote
#

is it using a database?

obtuse gale
#

no

#

@heady birch heres my entire controller

heady birch
#

Ah

#

Your service should be autowired

#

Make sure you annotate UserService with @Service

#

Then @Autowired UserService userService; in your controller

obtuse gale
#

ah oki

heady birch
#

When you do new UserService() spring cannot autowire the repository

#

So UserRepository will be null

obtuse gale
#

huh

#

how does autowiring work?

heady birch
#

In a spring application you don't do new on any main components

#

It creates them automatically when they are annotated with @Service @Controller e.g

obtuse gale
#

eyyyyyyy

#

its in the db

heady birch
#

Which makes them all basically a @Component

#

Nice

obtuse gale
#

now, if i wanna make a page that only people logged in can access how would i do so?

heady birch
#

You would create another template file and controller method

#

Then restricting access is down to the security config

obtuse gale
#

also i just realised i dont even have alogin form lol

heady birch
#

Yeah the login is not as hard

#

You only need to write the form, theres no DTO's involved

obtuse gale
#

ah

#

So do i just need to like

#

Get the values from the form, and check if they are the right one?

heady birch
#

First of all create a form

#
<head></head>
<body>
   <h1>Login</h1>
   <form action="/user/login" method='POST'>
      <table>
         <tr>
            <td>Username:</td>
            <td><input type='text' name='username' value=''></td>
         </tr>
         <tr>
            <td>Password:</td>
            <td><input type='password' name='password' /></td>
         </tr>
         <tr>
            <td><input name="submit" type="submit" value="submit" /></td>
         </tr>
      </table>
  </form>
</body>
</html>```
obtuse gale
#

yea

heady birch
#

In your security config add a matcher

#

.antMatcher("/user/login").permitAll()

#

I think it's permitAll

obtuse gale
#

mp[e

#

*nope

#

oh wait

heady birch
#

Yes

obtuse gale
#

did i do this right?java @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/user/registration").permitAll() .and().authorizeRequests().antMatchers("/user/login").permitAll(); }

#

i feel like i did something wrong lol

heady birch
#
    .antMatchers("/...").permitAll()
    .antMatchers("/...").permitAll()
    .anyRequest().authenticated()```
obtuse gale
#

It wont let me call .antMatchers twice

heady birch
#

Edited it, that should work

obtuse gale
#

ye

heady birch
#

You can put more than one url in a single antMatchers

#

.antMatcher("A", "B")

obtuse gale
#

oh

#

so does that just allow everyone for registration and login?

heady birch
#

yeah

obtuse gale
#

ah alright

#

what next?

heady birch
#

We need to make some beans in the same class

#

First of all, the password encoderjava @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); }

obtuse gale
#

do i make a new class for this?

heady birch
#

Nah

#

Same one

obtuse gale
#

Security Config?

heady birch
#

yeah

obtuse gale
#

alright

#

done

heady birch
#

Now an authentication provider

#
@Bean
public DaoAuthenticationProvider authenticationProvider() {
  DaoAuthenticationProvider auth = new DaoAuthenticationProvider();
  auth.setUserDetailsService(userService);
  auth.setPasswordEncoder(passwordEncoder());
  return auth;
}```
#

This tells spring to use our UserService (you will need to autowire that into SecurityConfig) for authentication

obtuse gale
#
UserDetailsService
Provided:
UserService``` on
#

auth.setUserDetailsService(userService);

heady birch
#

I think we did do this earlier

#

but make sure your UserService interface extends UserDetailsService

obtuse gale
#

ah that would be it

#

ye

heady birch
#
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
  auth.authenticationProvider(authenticationProvider());
}```
#

Make spring use our DaoAuthenticationProvider

#

That goes in security config as well

obtuse gale
#

yep

heady birch
#

Now the cool part

#

Add this to the end of your antMatchers bit...

#
.and()
.formLogin()
.loginPage("/user/login")
.passwordParameter("password")
.usernameParameter("username")
.loginProcessingUrl("/user/login")
.failureUrl("/login?error=true")
#

Cant remember if the processing url has to be different..

#

But if it does id just make it /user/login/p

#

and then the form action="/user/login/p"

obtuse gale
#

so now ive got

#
        http.authorizeRequests()
                .antMatchers("/user/registration").permitAll()
                .antMatchers("/user/login").permitAll()
                .anyRequest().authenticated()                
                .and()
                .formLogin()
                .passwordParameter("password")
                .usernameParameter("username")
                .loginProcessingUrl("/user/login")
                .failureUrl("/login?error=true");```
heady birch
#

yeah

#

make sure you specify loginPage

#

.loginPage("/user/login")

obtuse gale
#

alright

#

Wait cos i extended UserDetailsService my UserService class now wants me to implement get user by uysername or something

#

and it wants to return a UserDetails

heady birch
#

yeah

obtuse gale
#

how do i return userdetails?

prisma wave
#

how clever you are

heady birch
#

Lol

distant sun
#

:)))

heady birch
#

So I do this

#

@obtuse gale Did we do this?

#

You were talking about Authorities and stuff

#

And you had that code

austere moth
#

Hey guys, I'm trying to check if a player has a bed location set

#

if (p.getBedLocation() == null) {

#

Funnily enough I used this null check to prevent errors but it's throwing an error because it is null

#

Does anyone know how I can fix this?

prisma wave
#

if that's throwing an NPE then p is null

austere moth
#

It was the wrong thing to check

#

I set it to getBedSpawnLocation and it was fine

signal tinsel
#

@ocean quartz can I put subcommands in different classes for ur command framework?

#

Just trying out ur command framework for a client plugin

#

After that I'm prolly gonna make my own framework

ocean quartz
#

Yeah

signal tinsel
#

How do I do it then

ocean quartz
#

As long as they have the same @Command("") they are part of the same

#

All subclasses will be linked

signal tinsel
#

Ahhh

#

Do I need to register something or smth?

obtuse gale
#

Yes

#

Made a staff chat plugin ๐Ÿ˜„

signal tinsel
#

Nice

#

Similar to my chat channels plugin? Or just the command for it

obtuse gale
#

Well

#

/sc is to toggle

#

You can leave and join

#

And if you type in /sc other players won't see it

#

Unless they have the permission

signal tinsel
#

Ah

#

Yeah that's similar to chat channels

obtuse gale
#

But to be honest

#

In terms of code

#

Maybe not

signal tinsel
#

xD

#

Wait lemme find chat channels

#

I don't maintain the plugin anymore because its merged into my chat plugin but still available

hot hull
#

@signal tinsel Checkout my ploogin if you wanna see how to use Matt's framework, it's nothing fancy but it uses commands and subcommands, fairly organised

signal tinsel
#

link?

#

to github

hot hull
signal tinsel
#

also for bungeecord

#

would you just use plugin messaging?

obtuse gale
signal tinsel
#

Not bad

#

Nice plugin to begin with

obtuse gale
#

I create many plugins

#

Not just that xD

prisma wave
#

the images look broken

obtuse gale
#

Ya

#

It is a imgur

signal tinsel
#

Fix it

#

@obtuse gale I mean, to be honest it looks like a beginner plugin

distant sun
#

Haters gonna hate

signal tinsel
#

Honestly

#

I might add /premiumchat debug

#

Which upload all configuration and data files to hastebin together with things like all installed placeholder expansions

#

Would make it easier

#

To provide support atleast

obtuse gale
#

@heady birch yea i got that working, now if i enter the same email I just want to get like an error, it juts reloads to this

heady birch
#

It couldn't find the template

obtuse gale
#

what template is it looking for lol

heady birch
#

Do you throw an exception in UserService when they already have an email

#

And catch it in the controller

#

I usually catch the exception then add a message using model.addAttribute("error", "This email address is already in use")

obtuse gale
#

yea thats what i did

#
    @Autowired
    private UserService userService;
    @PostMapping("/user/registration")
    public ModelAndView registerUserAccount(@ModelAttribute("user") @Valid UserDto userDto, HttpServletRequest request, Errors errors, ModelAndView mav){
        try{
            User register = userService.registerNewUserAccount(userDto);
        } catch (UserAlreadyExistsException e) {
            mav.addObject("message","An account already exists with this email/username");
            return mav;
        }
        return new ModelAndView("successRegister", "user", userDto);
    }```
heady birch
#

Oh you return mav

#

Try returning new ModelAndView("(your template)", "message", "An account with this email already exists");

#

your template would be the normal registration one, not the successRegister one

obtuse gale
#

alrgiht

#

it just refreshs to a blank page now

lilac fractal
#

Is there a Maven repo for the DeluxeChat API?

hot hull
#

It doesn't have an api

#

Use the jar to access the methods

lilac fractal
#

Am I allowed to distribute the JAR with the source code for others though? Presumably that'd not be allowed for a premium plugin.

hot hull
#

You should only use it to reference the methods, and not actually shade the plugin in

lilac fractal
#

Yup but if the plugin using those references is open source, others won't have those references if they want to compile the plugin's source code themselves.

hot hull
#

Well they will if they're buyers of Dchat

#

Since they'll have a jar to reference to

lilac fractal
#

Yeah, not gonna happen, oh well, makes the support choice easy.

hot hull
#

You using maven or gradle or neither?

lilac fractal
#

Thank you.

#

Maven

hot hull
#

throw it in your local repo and it'll be easy, ofc those who want to compile it will also have to do that themselves

lilac fractal
#

Know how to local repo - but asking people to buy DeluxeChat to compile the plugin is not going to happen.

hot hull
#

Well the plugin depends on DeluxeChat

#

So what would be the point lmao

lilac fractal
#

softdepend for additional support - so will remove the softdepend and additional support

hot hull
#

Well I mean it's softdepend so you're not relying on dchat

#

Just have all the dchat methods in the class which they can remove if they aren't using it

lilac fractal
#

No worries, have saved them the effort of removing it themselves.

signal tinsel
#

wut

proper patio
#

Someone that knows C++?

signal tinsel
#

No

#

I hate development

#

4 hours debugging

#

1 minute solving the actual issue

wraith prawn
#

so how do i make a menu?

distant sun
wraith prawn
#

?

#

so how do i make a menu?

frail glade
#

lol

wraith prawn
#

how would i make a kitpvp menu?

prisma wave
#

do you know Java?

distant sun
#

ive heard he's a cool guy, what about him

prisma wave
#

idk

#

he can be kinda dumb

#

his brother Kotlin is much cooler

distant sun
#

jokes

rotund egret
#

Ahaha right? Who uses kotlin?

prisma wave
#

definitely not me

#

imagine using kotlin

remote goblet
#

Real devs use CSS for minecraft plugins ๐Ÿ˜Ž

pale shell
#

@remote goblet i thought real devs used skript ;)

remote goblet
#

They use skript and css

#

;)

pale shell
#

I hate skript btw

#

I downloaded the skript repo printed out every file and shredded it

remote goblet
#
.onEnable {
  // I dont know css
}
#

that sounds like a waste of paper

#

gross i forget i dont have nitro

#

on this server

#

:(

pale shell
#

Someone with 70k followers just followed me on twitter wtf

obtuse gale
#
.onEnable #server{
 registerListeners: url("com.aj3douglas.plugin.listeners.idk");
}
``` idk css lol
ocean quartz
#

What are you trying to do? xD

obtuse gale
#

no clue lol

#

If you could do spigot in css

forest forum
#

hey

#

could someone help me

#

@sleek creek

obtuse gale
forest forum
#

yes

#

@obtuse gale

obtuse gale
#

ok

#

let people know your problem in #development and wait for a response

forest forum
#

ight so im trying to decompile superboosters to add tokenenchat support

obtuse gale
#

ok

forest forum
remote goblet
#

MySQL sounds like al ot of work to learn

pallid gale
#

Heard clip loves mysql

remote goblet
#

I really should learn it

#

however

#

I don't have the patience to something else

hot hull
#

@remote goblet People say it's hard, but you'll get the hand of it soon, also you better be using hikari

remote goblet
#

You think i know what hikari is

#

๐Ÿคฆ

#

So far

#

MySQL looks like i'd mostly need to learn the key words such as select, from, delete, where, alter, update, ect

hot hull
#

HikariCP

#

google it

hot hull
#

@violet creek Hey, I saw you were playing around with tab completion packets a couple years ago, did you ever figure that out properly or?

remote goblet
hot hull
#

uSe HiKaRi

remote goblet
#

smd

hot hull
#

You'll thank me later, just do it

distant sun
#

Jumbo Hey, I saw you were playing around with tab completion packets a couple years ago, did you ever figure that out properly or?
@hot hull "a couple years ago" I bet you don't remember what you have done yesterday lmao xd

hot hull
#

I actually do! I can't remember for the day before that tho

distant sun
#

xd

hot hull
#

Ah yes I love it when IJ defaults to desktop as default directory -.-

violet creek
#

@hot hull yeah I did. You can just use protocollib for that, and use their premade wrapper for the packet.

Then you can remove and add keywords from the tabcompletion.

hot hull
#

L @distant sun

#

What version were you doing it on btw?

distant sun
#

1.2.5

hot hull
#

Cause I see that for 1.13 there's a new event, so just testing out what exactly the event does rn

heady birch
#

Hibernate

obtuse gale
#

Niall, do you know if it would be complicated to make a similar system to paypals messaging system? That might be really complicated lol

#

Basically its a live chat, but its not always live, like it can just be messaging

#

still gotta fix my registration/login tho :p

heady birch
#

Hm well it wouldn't be too hard

#

I would use websockets to be honest.. not that I know how to (with spring)

#

I've only ever done websockets with Netty and JavaWebsockets

#

Netty is a little bit of a pain

obtuse gale
#

hm alright, i gotta fix my login/registration first lol, if the email is the same the page just refreshes

signal tinsel
#

Ye

#

Websockets are quite easy

#

I did it in Python

remote goblet
obtuse gale
#

oof

#

@heady birch any clue why the page is just refreshing lol?

#

And then it appears blank

#

when the email matches

heady birch
#

Uh not sure

#

No error in console?

hot hull
#

Cuz you did something wrong :p

obtuse gale
#

na

#

ah frosty

#

that solves it all

hot hull
#

yw

obtuse gale
#

Why didnt i think of that

#

Would it be like a problem with the controller?

#
    @PostMapping("/user/registration")
    public ModelAndView registerUserAccount(@ModelAttribute("user") @Valid UserDto userDto, HttpServletRequest request, Errors errors, ModelAndView mav){
        try{
            User register = userService.registerNewUserAccount(userDto);
        } catch (UserAlreadyExistsException e) {
            new ModelAndView("registration", "message", "An account with this email already exists");
        }
        return new ModelAndView("successRegister", "user", userDto);
    }```
#

Whats a ModelAndView? And what would making a new one do?

#

hol up

#

maybe im just being stupid

heady birch
#

Oh my god

#

RETURN ๐Ÿ˜‚

#

return new

obtuse gale
#

omg bruh

#

how did i miss that lol

heady birch
#

Not sure if thats the problem it could well be

obtuse gale
#

now the page just refreshes, like it doesnt give any feedback that the email has an account

heady birch
#

Do you have your ${message} in tyhymeleaf?

obtuse gale
#

ah that would be the issue

#

is it just like this?

#

<h1 th:text="${message}"></h1>

heady birch
#

Yes but add a th:if="${message != null}" to that h1 as well

obtuse gale
#

ah

#

when i try to go to /user/login i get like a type=notFound error

#

i dont think i finished setting it up from the other day

heady birch
#

did you set .loginPage("/user/login")

#

Here

obtuse gale
#

ye

#
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/user/registration").permitAll()
                .antMatchers("/user/login").permitAll()
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .loginPage("/user/login")
                .passwordParameter("password")
                .usernameParameter("username")
                .loginProcessingUrl("/user/login")
                .failureUrl("/login?error=true");
    }```
heady birch
#

Do you have controller mapping?

#

@GetMapping("/user/login)
public String loginPage() {
return "your login template";
}

obtuse gale
#

nope

#

do i need to do postmapping as well?

#

whats the difference

heady birch
#

Just add a get mapping

obtuse gale
#

alrgioht

#

whats the difference tho lol

heady birch
#

Get just handles a normal request

#

Post handles like a form submission

obtuse gale
#

ah

#

isnt the login form considered a form?

heady birch
#

Yeah

#

But the post mapping would handle it

#

But we dont need one because spring handles it

obtuse gale
#

ah

heady birch
#

Unlike the registration form which does have a post mapping

obtuse gale
#

I did the form and the page refreshsed, idk if it worked or not lol

heady birch
#

Did it add ?error=true at the url?

obtuse gale
#

no

#

but even if i type random letters in each field it doesnt

heady birch
#

Change the processing URL to /user/login/p

#

And make the form th:action="@{/user/login/p}" see if that helps

obtuse gale
#

nope

heady birch
#

Page could be cached?

#

Make sure you dont resubmit the form

#

But refresh the form page then re enter details

obtuse gale
#

yea, i cleared my caches and then refreshed and re entered

#

wait im getting an erropr

#

If the email doesnt exist I get an NPE

#

and if it does exist even if the passwords right

#

I get a

#

InternalAuthenticationServiceException: failed to lazily initialize a collection of role: com.aj.website.User.roles, could not initialize proxy - no Session**

heady birch
#

Hm

#

Is your RoleRepository marked with @Repository

#

Or if you dont have one make sure you have a RoleRepository

obtuse gale
#

Lol i dont have one

#

Do I just need to extend JpaRepository?

heady birch
#

Ye

#

RoleRepository extends JpaRepository<Integer, Role>

obtuse gale
#

oh, its it integer roke? My user one is User Long

heady birch
#

It don't really matter

#

I mean you wont have trillions of roles

#

Int will easily handle it

obtuse gale
#

yea true

#

alright

#

anything in the interface?

heady birch
#

No

#

Although we may want to redo some of the ids in entitys at a later date

obtuse gale
#

alrgiht, whys that?

heady birch
#

I used GenerationType.IDENTITY to work with my old database

#

Building from scratch you can use GenerationType.AUTO and hibernate handles it

obtuse gale
#

ah

#

on enable I get

#

Error creating bean with name 'requestMappingHandlerAdapter' defined in class path resource ...

heady birch
#

Allows for batch queries so a bit of a performance gain

#

There will be another error

obtuse gale
#

yea

heady birch
#

Somewhere within the stacktrace

obtuse gale
#

Failed to instantiate [org.springframework.format.support.FormattingConversionService]: Factory method 'mvcConversionService' threw exception; nested exception is org.springframework.beans.facto

#

Error creating bean with name 'roleRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not a managed type: class java.lang.Integer

#

Is it meant to be Role Integer

#

Not Integer role

heady birch
#

Maybe

#

Yeah

#

Sorry lol

obtuse gale
#

same thing

#

like from earlier not the startup error

#

InternalAuthenticationServiceException: failed to lazily initialize a collection of role: com.aj.website.User.roles, could not initialize proxy - no Session**

heady birch
#

@ManyToMany(fetch = FetchType.EAGER)

obtuse gale
#

where?

heady birch
#

Replace your @ManyToMany with that

#

In User

obtuse gale
#

ah

#

if the email exists

#

Encoded password does not look like BCrypt

#

IF the username doesnt exist i get an NPE

heady birch
#

Oh yeah

#

Delete your account in the database

#

In your UserService account creation code ensure the password is actually encoded

#

user.setPassword(passwordEncoder.encode(password));

#

passwordEncoder can be autowired

obtuse gale
#

alright

#

Now it just refreshs, and nothing happens

#

like when i type in and login

heady birch
#

In your ant matchers add "/user/login/p"

#

So it lets normal users go there

obtuse gale
#

Still just nothing happens when i type in the right password or the wrong one

#

NPE if i type in the username or wrong email

heady birch
#

Probably because there is no success url

#

Lets sort out the npe first

#

What is the NPE?

obtuse gale
#

its at this line

#

return new org.springframework.security.core.userdetails.User(user.getEmail(),user.getPassword().toLowerCase(), true,true,true,true, getAuthorities(user.getRoles()));

heady birch
#

Add this above that

#
            throw new UsernameNotFoundException("Invalid username");
        }```
#

That exception is built in to spring

obtuse gale
#

ah ok

#

I want users to be able to login via username as well, not just email

#

That also means ill need a check if the username is already taken

heady birch
#

You can probably adapt it

#

In your user repository add a method like this

#

findByUsernameEqualsOrEmailEquals(String username, String email);

obtuse gale
#

alright

heady birch
#

Then use that instead of what your using to get the User

obtuse gale
#

does that replace getUserByEmail?

heady birch
#

Yeah

obtuse gale
#

alright

#

Now its telling me i need to implement loadUserByUsername do i just do the same process as email for htat?

#

actually nvm

heady birch
#

?

obtuse gale
#

yea so its telling me my old method doesnt override anymore, and it made me implement a new one, and that new one doesnt take in an email

#

in UserService this is

heady birch
#

Keep that method how it is

obtuse gale
#

Its telling me it doesnt override anymroe

signal tinsel
#

God fucking damnit I broke crafting

#

I have absolutely no fucking clue how I managed to do that

heady birch
#

Think I explained badly

#

We dont change parameters in loadByUsername

#

Can you send the UserService source?

obtuse gale
#

what

#

kk one sec

#

=paste

compact perchBOT
#
HelpChat Paste

Please use a paste service to share configs, errors, code and long logs.
โ€ข HelpChat Paste

heady birch
#

We still accept the "username" but use the username to lookup as an email or username

obtuse gale
#

and there are errors on that

#

cos getUserByEmail needs a username as well now

heady birch
#

User user = userRepository.findUserByUsernameEqualsOrEmailEquals(email, email);

signal tinsel
#

Yikes long methodnames

obtuse gale
#

why do we use email twice?

heady birch
#

Because that method accept email and username

#

The email we provide could be either

#

Whatever is in the username or email box

#
@Repository
UserRepository {
  User findUserByUsernameEqualsOrEmailEquals(String username, String email);
}```
obtuse gale
#

ah

heady birch
#

Just a pseudocode

obtuse gale
#

ye

heady birch
#

Add that method to your user repository interface

#

A spring is clever and automatically implements it

obtuse gale
#

alrighty

#

thats the npe dealt with]

#

now just nothing happens lol

heady birch
#

You logged in successfully I expect

obtuse gale
#

i mean

#

nothing happens

heady birch
#

As in?

#

Page refreshes, redirects, stuck loading

obtuse gale
#

the page just refreshe, no error, its as if nothings happend

heady birch
#

In your loginForm() section is security config

#

.defaultSuccessUrl("/", true)

#

Put where you want it to redirect you when logged in

obtuse gale
#

alright

#

nope,

#

same thing

heady birch
#

is ?error=true in the url bar

obtuse gale
#

no

heady birch
#

Because any way we need to show the error message to the user

#
<div class="alert alert-danger" th:if="${param.error}"
         th:with="errorMsg=${session['SPRING_SECURITY_LAST_EXCEPTION'].message}">
        <span th:text="${errorMsg}">Error</span>
    </div>
#

I use this but this also uses bootstrap so just remove the class= part

obtuse gale
#

alright

heady birch
#

But im not too sure about that otherwise

obtuse gale
#

lol still nothing

heady birch
#

Lets see controller code

obtuse gale
#

=paste

compact perchBOT
#
HelpChat Paste

Please use a paste service to share configs, errors, code and long logs.
โ€ข HelpChat Paste

obtuse gale
signal tinsel
heady birch
#

Yeah fine, what about login.html

obtuse gale
heady birch
#

This is odd

#

Only thing i can think of is th:method="POST"

obtuse gale
#

alright

#

do i need to change the thing to @GetPost or na

heady birch
#

No

#

Spring handle that

obtuse gale
#

ah

#

rip

#

still nothing

heady birch
#

Did you delete your user like I said earlier (when we did password encryption)

obtuse gale
#

yea

#

in the db its encrypted

heady birch
#

Can you send security config?

obtuse gale
heady birch
#

Maybe chuck on .permitAll() on the end of failureURL

obtuse gale
#

alright

heady birch
#

See what happens

obtuse gale
#

get this everytime i click login

heady birch
#

.failureUrl("/user/login?error=true");

#

So the reason it kept refreshing because we didnt have permission to process the login for some reason, so it redirects us to a the login

obtuse gale
#

ah

heady birch
#

If we access any page without permission spring redirects us to the login

obtuse gale
#

ah thats good

#

imma delete myself from the db and re register just to make sure my credentials are actually bad lol

#

yeas it just says bad credentials everyime

heady birch
#

Spring will always say "bad credentials" and wont say wether its username password, e.g I looked into saying what it specifically is.. But it's actually more secure to just say that general message

#

Hm

#

I dont think you should convert your password to lower case in UserService

obtuse gale
#

alright

#

am i gonna have to re insert myself to the db?

heady birch
#

No

obtuse gale
#

eyyyyy

#

now like

#

eill pages be only accesible if you logged in, unless i permit all?

heady birch
#

yeah

obtuse gale
#

ah

#

nice

#

this is kinda random, but in theory could I integrate JDA into a website?

#

like in the same code

heady birch
#

Totally yeah

#

I integrate netty sometimes

obtuse gale
#

no clue what that is lol

heady birch
#

like networking library

obtuse gale
#

ah

#

now imma do some frontend stuff so this looks presentable

#

What do I do if i want like either LOGIN or THEIRUSERNAME in like the top left corner

#

like on the main page

heady birch
#

In the controller I usually add the current user as a atttribute to the model

#

then check if it's null

obtuse gale
#

where do i get the user from?

heady birch
#
@GetMapping
public String homepage(Model model, @AuthenticationPrincipal User user) {`
if (user != null) {
  model.addAttribute("user", userRepository.findUserByUsername(username));
}
return "homepage";
}
#

Now before this works

#

In your UserService where we create the spring UserDetails

obtuse gale
#

So does getmapping just get it for everything unless its already assigned something else?

#

like by itself with no params

heady birch
#

No

#

GetMapping just handles an HTTP get

#

It can still handle ?= in the url

#

But not form submissions

#

to handle everything use @RequestMapping

obtuse gale
#

huh

heady birch
#

basically just use a GetMapping

obtuse gale
#

alright

heady birch
#

Oops

#

Oh I see what you mean now

#

@GetMapping
is equivalent to
@GetMapping("/")

obtuse gale
#

ah

heady birch
obtuse gale
#

ye

#

In your UserService where we create the spring UserDetails
wdym

heady birch
#

Ignore that

#

We created UserDetails with user.getEmail() which is fine

#

So we need to make sure we get the User by email in the controller

obtuse gale
#

model.addAttribute("user", userRepository.findUserByUsernameEqualsOrEmailEquals(user.getEmail(),user.getEmail()));?

#

then in my html file i just add like something like th:idk="${user} or something along those lines?

heady birch
#

userRepository.findUserByEmail(user.getUsername())

#

then in my html file i just add like something like th:idk="${user} or something along those lines?
@obtuse gale Yeah

#

userRepository.findUserByEmail(user.getUsername())
@heady birch You need to use to get the User

obtuse gale
#

well my userrepo only has

#

userRepository.findUserByUsernameEqualsOrEmailEquals(user.getEmail(),user.getEmail())

heady birch
#

Oh just create User findUserByEmail(String email); in their

#

In this case @AuthenticaionPrinciple User user is the Spring UserDetails class

obtuse gale
#

o]

#

so i need to change my imports?

heady birch
#

No

#

keep @AuthenticationPrinciple UserDetails userDetails then

obtuse gale
#

ah

#
    @GetMapping
    public String index(Model model, @AuthenticationPrincipal UserDetails user) {
        if (user != null) {
            model.addAttribute("user", userRepository.findUserByEmail(user.getUsername()));
        }
        return "index";
    }```
heady birch
#

Im refering to old code I think this can be done better with a controller advice

obtuse gale
#

huh?

heady birch
#

@ControllerAdvice(annotations = Controller.class)
public class UserControllerAdvice {

    @Autowired
    UserRepository userRepository;

    @ModelAttribute("user")
    public User getUser() {
      UserDetails userDetails = (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();

      if (userDetails == null) {
        return null;
      }
      return userService.findUserByEmail(userDetails.getUsername());
}```
#

Make this a class

obtuse gale
#

which user to i use

heady birch
#

Import your User class

#
@GetMapping
public String index() {
  return "index";
}```
Then I think you can just do this in your main controller
obtuse gale
#

alrihgt

#

java.lang.String cannot be cast to class org.springframework.security.core.userdetails.UserDetails

heady birch
#
@ControllerAdvice(annotations = Controller.class)
public class UserControllerAdvice {

    @Autowired
    UserRepository userRepository;

    @ModelAttribute("user")
    public User getUser() {
      Authentication auth = SecurityContextHolder.getContext().getAuthentication();
      if (auth == null) {
        return null;
      }

      return userService.findUserByEmail(auth.getName());
    }
}```
#

Maybe try this

obtuse gale
#

userservice is meant to be repo right?

#

orr

#

anyway i gotta sleep its like 2am

heady birch
#

Oh yeha

#

userRepository

#

Have a good night

#

Revisiting spring has made me realise I can improve my code ๐Ÿ™‚

obtuse gale
#

yea, just for tomomrow what do i use for the html? Its like th:something="${user}" rihgt?

heady birch
#

Yep

#

To get username you would do

#

<span th:text="${user.username}">

#

<span th:text="${user.email}">

#

e.g

#

Can put that in other things besides a <span>

#

and you can access anything in your User object

obtuse gale
#

alright

#

thx

heady birch
#

๐Ÿ‘

heady birch
#

Lol, thanks

#

Wrong channel

signal tinsel
#

Damn a maxrankup command is fucking easy

signal tinsel
#

Time to get to work on my next client's plugin

signal tinsel
#

What do yall do? Test while developing like every day or finish the plugin and then test?

obtuse gale
#

I personally test while developing, cos i fk stuff up alot lol

signal tinsel
#

I usually don't

obtuse gale
#

More specifically, I do one feature of the plugin, test

signal tinsel
#

ah

#

I just test at the end

#

Expect to have to fix 10 bugs before being able to start the plugin

#

Then another 15 upon joining the server

#

Then another 10-15

#

Then I'm done

ocean quartz
#

I do something, test, do more, test, and repeat until it works

signal tinsel
#

I only do that for plugin updates

prisma wave
#

Unit test master race

#

I try to only do integrated testing for things like GUIs

signal tinsel
#

LOL

signal tinsel
#

Anyway im off to bed

#

its nearly 3am

#

NIGHT

cursive breach
chilly jungle
#

Is there a legit way to unregister a command from the server

#

Tab completion and all

ocean quartz
#

@chilly jungle I did a few tests and well.. kinda?
For some reason it still shows on the tab complete

frail glade
#

You have to remove it from knownCommands

obtuse gale
#

Do you guys prefer intellij

#

Or eclipse

quiet depot
#

intellij

ocean quartz
#

I did it yeah Glare still shows somehow
I could find a way around it though, like saving the removed command name to a list and canceling it from the tab complete

frail glade
#

I guess that's a way. Just annoying.

ocean quartz
#

I could play with the command map tomorrow to see if i can completely remove it

obtuse gale
#

Do I actually need to do this?

#

FileConfiguration config;
File cfile;

    config = getConfig();
    config.options().copyDefaults(true);
    saveConfig();
    cfile = new File(getDataFolder(), "config.yml");
#

Since I can have the default one

chilly jungle
#

@ocean quartz thats as far as I have gotten

ocean quartz
#

Yeah, tomorrow I'll try removing the tab complete as well and will let you know

obtuse gale
#

I am wondering what's behind the scene of Barry's random xp generator wheel

quiet depot
#

a lot of images

obtuse gale
#

I mean, idk which spin type it is

quiet depot
#

=xp spin

compact perchBOT
quiet depot
#

what's the command

obtuse gale
#

Lol

quiet depot
#

=xp wheel

compact perchBOT
quiet depot
#

=wheel

compact perchBOT
#
XP Wheel Result...
quiet depot
#

yeah it's just a whole lotta images & gifs

obtuse gale
#

Is it actually ๐Ÿค”

quiet depot
#

pretty sure

hot hull
#

It is

obtuse gale
#

No way i am gonna add 100+ imgs on different angle

hot hull
#

Cube showed all the images for it once

obtuse gale
#

Wait are those all exact timed (the spin speed)

#

@hot hull where ๐Ÿ‘€

hot hull
#

Idfk that was months ago

quiet depot
hot hull
#

Like 50 pastes daily are mine lmao

obtuse gale
#

Btw reason i asked it was I would like to add the spin-to-win wheel on image map

#

But seeing that behind the scene for it with barry... no way

quiet depot
#

damn like 90% of our requests are from the us (helpch.at)

hot hull
#

Just make a gif which does like 6 rotations, then just play the gif at a specific timepoint, and put an ending image when it finishes

quiet depot
hot hull
#

Find Slovenia on there piggy

obtuse gale
#

I am wondering if they are all exact timed on gif

quiet depot
#

slovenia: n/a

hot hull
#

Wow

#

Scam

obtuse gale
#

๐Ÿ˜‚

hot hull
#

I mean it makes sense, but still

obtuse gale
#

Find Vietnam on there pls

#

I think i pasted a lot recently

quiet depot
#

vietnam 228

obtuse gale
#

Sure ๐Ÿ˜‚

quiet depot
#

apparently brazil tries to attack the site a lot

#

343 threats from brazil in the last 24 hours

obtuse gale
#

I thought it's ddos protected ?

quiet depot
#

yeah, that's blocked attacks

#

not necessarily ddos attacks

#

just some sort of attack

obtuse gale
#

Also, about the wheel, are the gif having exact time length or what, because there is no way i will make it in obvious way

quiet depot
#

idk how it works behind the scenes

obtuse gale
#

Or are all the spinning speed gif are the same

#

Cube knows ๐Ÿ˜‚

#

I am actually gonna use the old school wheel on the map then, by creating a flash on the selected choice (16 imgs, 8 choices)

pallid gale
#

Its pretty easy

#

You can makes gifs not loop

#

So there are 8 gifs

#

all ending on a different slot

#

once the gif finishes barry edits the message to swap out the gif with a still image of the last frame

obtuse gale
#

With the wheel that falls into different angle of the selection pointed, how would you do it

#

Is the last frame gotten by manual programming?

pallid gale
#

it never falls on a different angle

#

it always finishes perfectly in the middle of a section

obtuse gale
#

How hard would it be with spring to make it so its like a messaging system with spring, that can only be seen by staff

#

So its like a private ticket with staff

heady birch
#

Live chat or Like a github issue/ticket system

obtuse gale
#

Are you familiar with paypals live chat system?

#

Its like a live chat, but its not always live, like if someones not available the message just stays there until someone is, and can reply

heady birch
#

No

obtuse gale
#

hard?

heady birch
#

Don't really know

obtuse gale
#

@pallid gale it's different on the Barry's ban wheel i think

#

Sometimes i see the pointer not actually point to the center

#

No idea why I can't download this image but...

#

Idk it's mistake from aligning or is that how it's supposed to be different lol

heady birch
#

Should I use Kotlin for a library? Only downside is my library will include the kotlin stdlib

#

And this stupid generation.

#

@topaz bay

pallid gale
#

@obtuse gale its rigged

#

theres only one gif

#

one outcome

#

and its that

distant sun
#

"People that had one job and failed"

steel heart
#

Cj

hot hull
#

Why Cj

#

Just why

steel heart
#

I can see why you are an eclipser

quick flume
#

fools

steel heart
#

Respect(: