月度存档: 五月 2017

AssetBundle解析音频文件

使用 Unity Studio 解析 ab 时,发现在 obb 中的 ab 未解析出来。

disunity 又N年未更新了。

用 ABE 发现可以提取出 ab data和dump信息,但是工具无自动导出音频功能。

只能自己手动处理下了。

1、obb本身是压缩的ab格式,需要先将其解压,用 Unity Studio 解压即可。

2、对于这部分文件 UnityStudio无法正常解析(有时间可以看下源码找下原因),使用 UAB 打开后,将AudioClip 提取出 raw data(文件名类似: Select-voice-02_AudioClip_117_1854432161) ,提取出 raw dump (文件名类似:Raw_117_1854432161.dat)

我们需要做的事件就是将 ab的文件头从 raw dump中去除,即可得到音频文件。

0 AudioClip Base
 1 string m_Name = "Select_voice_02"
 0 int m_Format = 2
 0 int m_Type = 13
 0 bool m_3D = false
 1 bool m_UseHardware = false
 0 int m_Stream = 2
 0 vector m_AudioData
  1 Array Array (95608 items)

raw data 中列明了文件头信息,对我们有用的是 Array Array 行,指明了 音频文件的大小长度。

之后只需要从 raw dump中取最后 arraylength+1 字节内容即为音频内容。

三个story工具

http://www.nwn2toolset.dayjo.org/ToolsetTuts/conversations/writingconvos.html

https://twinery.org/

 

http://www.inklestudios.com/inklewriter/

Json web token (JWT) 相关介绍

最近看了vuejs,看到了vue-auth中一个jwt-auth,发现几年不关注,前端完全是全新的领域了。

这里列下jwt相关的资源,供快速了解jwt.

https://jwt.io/introduction/

https://github.com/szerhusenBC/jwt-spring-security-demo

https://www.toptal.com/java/rest-security-with-jwt-spring-security-and-java

spring boot security如何集成JWT.

java相关的jwt库太多了。

apache有oltu

spring有spring-security-jwt

还有其它一些第三方开源库

1、服务器端添加 jwt 支持:

配置spring security

package com.elex.gm.spring;

import java.security.SecureRandom;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import com.elex.gm.service.UserManager;
import com.elex.gm.spring.jwt.JWTAuthenticationFilter;
import com.elex.gm.spring.jwt.JWTLoginFilter;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    public BCryptPasswordEncoder passwordEncoder() throws Exception {
        return passwordEncoder;
    }

    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/static/**").antMatchers("/hello/**").antMatchers("/api/open/**");
    };

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http

                .authorizeRequests()

                .antMatchers("/api/gm/**").hasAnyRole("ADMIN", "USER")

                .antMatchers("/api/user/**").hasAnyRole("USER")

                .and()

                .formLogin()

                .loginProcessingUrl("/api/user/login")

                .permitAll()

                .and()

                .logout()

                // .logoutUrl("/api/open/logout")

                .and()

                .httpBasic()

                .and()

                .addFilterBefore(new JWTLoginFilter("/api/user/login", authenticationManager()),
                        UsernamePasswordAuthenticationFilter.class)

                .addFilterBefore(new JWTAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);

        http.csrf().disable();
        http.headers().frameOptions().disable();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userManager).passwordEncoder(passwordEncoder);
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
    }

    @Autowired
    private UserManager userManager;

    private BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(16,
            new SecureRandom("j^E1)y*)HL2gT,es+ODa!0+j^L1I3+6I".getBytes()));
}

 

JWTLoginFilter:

package com.elex.gm.spring.jwt;

import java.io.IOException;
import java.util.Map;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.http.HttpStatus;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.jwt.Jwt;
import org.springframework.security.jwt.JwtHelper;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;

import com.alibaba.fastjson.JSON;
import com.elex.gm.model.User;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

public class JWTLoginFilter extends AbstractAuthenticationProcessingFilter {

    public JWTLoginFilter(String defaultFilterProcessesUrl, AuthenticationManager authenticationManager) {
        super(defaultFilterProcessesUrl);
        setAuthenticationManager(authenticationManager);
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
            throws AuthenticationException, IOException, ServletException {

        String username = request.getParameter("username");
        String password = request.getParameter("password");

        if (username == null) {
            username = "";
        } else {
            username = username.trim();
        }
        if (password == null) {
            password = "";
        } else {
            password = password.trim();
        }
        return getAuthenticationManager()
                .authenticate(new UsernamePasswordAuthenticationToken(username, password, Lists.newArrayList()));
    }

    @Override
    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain,
            Authentication authResult) throws IOException, ServletException {
        User user = (User) authResult.getPrincipal();

        Map<String, Object> tokenMap = Maps.newHashMap();
        tokenMap.put("id", user.getId());
        tokenMap.put("name", user.getUsername());
        tokenMap.put("roles", user.getRoles());
        Jwt jwt = JwtHelper.encode(JSON.toJSONString(tokenMap), JWTKey.hmac);

        String token = jwt.getEncoded();
        response.setHeader("Authorization", token);
    }

    @Override
    protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,
            AuthenticationException failed) throws IOException, ServletException {
        response.setStatus(HttpStatus.UNAUTHORIZED.value());
    }

}

JWTAuthentication:

package com.elex.gm.spring.jwt;

import java.io.IOException;
import java.util.List;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.jwt.Jwt;
import org.springframework.security.jwt.JwtHelper;
import org.springframework.web.filter.GenericFilterBean;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;

public class JWTAuthenticationFilter extends GenericFilterBean {
    private static final String JWT_HEADER = "Authorization";

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        try {
            String token = ((HttpServletRequest) request).getHeader(JWT_HEADER);
            Jwt jwt = JwtHelper.decodeAndVerify(token, JWTKey.hmac);
            JSONObject json = JSON.parseObject(jwt.getClaims());

            String username = json.getString("name");
            String roles = json.getString("roles");
            List<SimpleGrantedAuthority> list = Lists.newArrayList();
            if (!StringUtils.isEmpty(roles)) {
                for (String role : roles.split(",")) {
                    if (!StringUtils.isEmpty(role)) {
                        list.add(new SimpleGrantedAuthority("ROLE_" + role));
                    }
                }
            }
            Authentication authentication = new UsernamePasswordAuthenticationToken(username, null, list);
            SecurityContextHolder.getContext().setAuthentication(authentication);
        } catch (Exception e) {
            // e.printStackTrace();
        }
        chain.doFilter(request, response);
    }
}